Mongoose Populate not returning related data - mongodb

I have the following Models:
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const imputerSchema = new mongoose.Schema({
dninie: {
type: String,
trim: true,
},
name: {
type: String,
trim: true,
required: true,
},
lastname: {
type: String,
trim: true,
required: true,
},
second_lastname: {
type: String,
trim: true,
},
phone : {
type: Number,
unique: true,
trim: true,
},
qr: {
type : String,
unique: true,
default: Date.now
}
});
module.exports = mongoose.model('Imputer', imputerSchema)
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const imputationSchema = new mongoose.Schema({
qr: {
type: String,
trim: true,
required: true,
ref: 'Imputer',
},
imputation_date: {
type: String,
default: Date.now,
required: true,
},
coordinates: {
type: [Number, Number],
index: '2d',
},
});
module.exports = mongoose.model('Imputation', imputationSchema);
and I trying to make a query like this:
Imputation.find()
.populate('imputer.qr')
.exec()
.then(docs => console.log(docs));
I also try
Imputation.find()
.populate('imputer')
.exec()
.then(docs => console.log(docs));
But I'm only got the documents on the imputation model without the field on the imputers model.
Here are some screenshots of how the documents look

Change your imputationSchema as follows:
const imputationSchema = new mongoose.Schema({
qr: {
type: mongoose.Types.ObjectId, ref: "Imputer",
trim: true,
required: true,
},
// other fields...
});
and then query like this:
Imputation.find()
.populate('qr')
.exec()
.then(docs => console.log(docs));

Related

mongoose validator not working as expected

i want to add batch,department,stream,id fields to the schema depending if usertype is “Student”,i do not understand why,but sometimes it adds the fields sometimes not.forexample if i created a user with usertype “Student” first it does not add the fields,but after that when i created a user with usertype “Teacher” or “Admin” it asks me the fields are required meaning it add the fields and this happens vice versa.why any way to fix this issue?please help guys.
what i have tried well,i have asked chatGpt but no answers i mean just the answers do not solve the issue.
here is the code
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema(
{
fullName: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
userType: {
type: String,
required: true,
},
phoneNumber: { type: String, required: true },
password: { type: String, required: true },
approved: { type: Boolean, default: true },
},
{
timestamps: true,
}
);
userSchema.pre("validate", function (next) {
if (this.userType === "Student") {
this.constructor.schema.add({
batch: {
type: Number,
required: true,
},
department: {
type: String,
required: true,
},
stream: {
type: String,
required: true,
},
id: { type: String, required: true }, //, unique: true
});
}
next();
});
const userModel = mongoose.model("users", userSchema);
module.exports = userModel;

Typescript + mongodb : create index

Hello I'm having trouble creating an index to delete automatically expired rows something like:
db.eventlog.createIndex( { created_at: 1 }, { expireAfterSeconds:
3600, partialFilterExpression: { state: 'TMP' } } );
my code:
export type PasswordRecoveryAttributes = {
employee_id: string;
email: string;
token: string;
used: boolean;
expiration: Date;
latitude: string;
longitude: string;
};
const PasswordRecoverySchema = new Schema(
{
employee_id: {
type: String,
trim: true,
required: true,
},
email: {
type: String,
lowercase: true,
trim: true,
required: true,
},
token: {
type: String,
trim: true,
required: true,
},
used: {
type: Boolean,
trim: true,
default: false,
required: true,
},
expiration: {
type: Date,
},
ip: {
type: String,
trim: true,
required: true,
},
latitude: {
type: String,
trim: true,
required: false,
},
longitude: {
type: String,
trim: true,
required: false,
},
},
{
timestamps: true,
},
);
type PasswordRecoveryDoc = Document & PasswordRecoveryAttributes;
export interface PasswordRecoveryDocument extends PasswordRecoveryDoc {}
// For model
export interface PasswordRecoveryModel extends Model<PasswordRecoveryDocument> {}
export default mongoose.model<PasswordRecoveryDocument>(
'PasswordRecovery',
PasswordRecoverySchema,
);
connection:
(async () => {
const mongoUserPass = mongoConfig.username
? `${mongoConfig.username}:${mongoConfig.password}#`
: '';
const connection = await mongoose.connect(
`mongodb://${mongoUserPass}${mongoConfig.host}:${mongoConfig.port}/${mongoConfig.database}`,
{
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
useFindAndModify: false,
},
);
})()
But I’m not able to imagine how to do this in typescript and
Mongo
Suggestions: It would help your work if your can think in terms of
Mongoose, which was meant for this, it helps you in this task to model your objects for MongoDb
To answer your question:
class EmployeePassword {
...
#index(1, { unique: true, sparse: true, name: 'email_unique_index' }) email: string;
#index() someId: number;
}
Now with Mongoose a good example:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const EmployeePassword = new Schema({
employee_id: string;
email: string;
token: string;
used: boolean;
expiration: Date;
latitude: string;
longitude: string;
});

Populate a property of a mongoose schema with all the data in another collection

I have a model with articles, and would like to populate an array of data with all the documents in a collection.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ArticlesSchema = new mongoose.Schema({
path: {
type: String,
required: true,
unique: true,
},
base_headline: {
type: String,
required: true,
},
intro: {
type: String,
required: true,
},
featured_image: {
type: String,
required: true,
},
author: {
type: String,
required: true,
},
platform_filter: {
type: String,
},
free_filter: {
type: String,
},
content_type: {
type: String,
required: true,
},
data: [{ type: Schema.Types.ObjectId, ref: 'DesignProducts' }],
date: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model('Articles', ArticlesSchema);
The data property should be populated with all documents in the DesignProducts collection.
I tried running this but the data array is still empty:
Article.findOne({ path: slug }).populate('data').exec();
Here is what the designProducts model looks like:
const mongoose = require('mongoose');
const DesignProductsSchema = new mongoose.Schema({
name: {
type: String,
required: true,
unique: true,
},
intro: {
type: String,
required: true,
},
website: {
type: String,
required: true,
},
date: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model('DesignProducts', DesignProductsSchema);
This array should be populated with all the documents in the DesignProducts collection:

MongoDB gives duplicated error when I use the same name that is unique: false

I try to save and update an entry with upsert, checking the unicity (is that the word? uniqueness?), of my own id key, called id. However, when I create a new entry, with a new id, if I write the same name for the object, the error happens:
errmsg: 'E11000 duplicate key error collection:
app.ticket index: nombre_1 dup key: { nombre: "James
Bond" }', [Symbol(mongoErrorContextSymbol)]: {}
The controller looks like this:
exports.guardarParte = (req,res,next) =>{
const newParte = {
id: req.body.id,
nombre: req.body.nombre,
telefono: req.body.telefono,
ref: req.body.ref,
marca: req.body.marca,
fecha: req.body.fecha,
averia: req.body.averia
}
parte.updateOne({id:newParte.id},{$set:newParte}, {upsert:true}, (err,parte)=>{
if(err && err.code === 11000){
return res.status(409).send("El parte ya existe(?)"+err);
}
if(err){
return res.status(500).send("No se ha podido crear el parte");
}
res.send(parte);
})
}
The model looks like this:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
mongoose.set('useCreateIndex',true);
mongoose.set('useUnifiedTopology',true);
const reparacionSchema = new Schema({
id: {
type: String,
required: false,
trim: true,
unique: true
},
nombre: {
type: String,
required: false,
trim: true,
unique: false
},
telefono: {
type: Number,
required: false,
trim: false
},
ref: {
type: String,
required: false,
trim: false
},
marca: {
type: String,
required: false,
trim: false
},
fecha: {
type: Date,
required: false,
trim: false
},
averia: {
type: String,
required: false,
trim: false
},
},{
timestamps: true
});
module.exports = reparacionSchema;
As you see in the model, nombre is set as unique:false. knowing this, I don't get why the error.

Push a sub-subdocument on a Mongoose Schema [duplicate]

This question already has answers here:
Mongodb $push in nested array
(4 answers)
Closed 3 years ago.
Consider these 3 schemas and hierarchy: A Project has multiple Stages, a Stage has multiple Events.
For pushing a new Stage into a Project, I do this:
Project.findOneAndUpdate(
{ slug: projectSlug },
{ $push: { stages: myNewStage } },
).then((post) => res.status(201).json({
message: 'stage created successfully',
data: post,
})).catch((error) => {
return res.status(500).json({
code: 'SERVER_ERROR',
description: 'something went wrong, Please try again',
});
});
But, how can I push a new event into a Stage? As far as I've seen, a subdocument does not have the same properties as a document (such as find, findAndUpdate).
My actual schemas:
PROJECT SCHEMA
const mongoose = require('mongoose');
const Stage = require('./Stages').model('Stages').schema;
const projectSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
},
slug: {
type: String,
trim: true,
required: true,
lowercase: true,
unique: true,
},
clientSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
stages: [Stage],
startDate: {
type: Date,
trim: true,
required: true,
},
endDate: {
type: Date,
trim: true,
required: false,
},
},
{
timestamps: true,
});
module.exports = mongoose.model('Projects', projectSchema);
STAGE SCHEMA
const mongoose = require('mongoose');
const Event = require('./Events').model('Events').schema;
const stageSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
},
slug: {
type: String,
trim: true,
required: true,
lowercase: true,
unique: true,
},
clientSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
projectSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
events: [Event],
},
{
timestamps: true,
});
module.exports = mongoose.model('Stages', stageSchema);
EVENT SCHEMA
const mongoose = require('mongoose');
const Comment = require('./Comments').model('Comments').schema;
const eventSchema = new mongoose.Schema({
_id: {
type: String,
trim: true,
lowercase: true,
},
userEmail: {
type: String,
trim: true,
required: true,
lowercase: true,
},
text: {
type: String,
},
imgUrl: {
type: String,
},
documentUrl: {
type: String,
},
stageSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
clientSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
projectSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
comments: [Comment],
},
{
timestamps: true,
});
module.exports = mongoose.model('Events', eventSchema);
To push a new event into your stages array given that you have the projectSlug and stageSlug, you can do this:
Project.findOneAndUpdate(
{
$and: [
{ slug: projectSlug },
{ 'stages.slug': stageSlug },
]
},
{
$push: { 'stages.$.events': newEvent }
}
)
.then(() => {})
.catch(() => {});