Mongo: query on subdocs - node.js

Hello I have this problem when checking if a subdocument exist before pushing a new subdocument.
var UserSchema = new Schema({
name : String,
app_key : String,
app_secret : String,
tasks : [{type: Schema.ObjectId, ref: 'Task'}] // assuming you name your model Task
});
var TaskSchema = new Schema({
name : String,
lastPerformed : Date,
folder : String,
user : {type: Schema.ObjectId, ref: 'User'} // assuming you name your model User
});
With this, your query for all users, including arrays of their tasks might be:
User.findOne({...}).populate('tasks').run(function(err, user) {
var subdoc = user.tasks.id(mytask.id);
if(subdoc){
//not exist
//push
}
});
This is the error:
TypeError: Object has no method 'id'

You are getting that error because there is no 'id' field defined for the 'tasks' subdocument. You might have meant 'user.tasks._id', which will return the ObjectId that MongoDB adds to its documents by default.

Related

What data structure should i use in mongoDB

I am making a small project in MEAN stack but I can not figure out what data structure to use.
So, in this case, I don't have any reference in the store I just fetch store when a person asks for his or her stores.
var personSchema = Schema({
_id : Number,
name : String,
stores: [{ type: Schema.Types.ObjectId, ref: 'Store' }]
});
var storeSchema = Schema({
_id : Number,
title : String
});
AND:
In this case, I give the store a reference of the person so when a person asks for his or her stores I fetch all the store which has a reference to the person.
var personSchema = Schema({
_id : Number,
name : String
});
var storeSchema = Schema({
_id : Number,
owner : { type: Schema.Types.ObjectId, ref: 'Person' },
title : String
});
Which one is better approach?
First one is better to use as it helps in clean code and queries.

Mongoose: Referencing a subdocument from another subdocument AND population

I have a document model called school which in turn has two subdocuments:
students
class
Each student belongs to one class.
var classSchema = new Schema({
name: {type : String}
});
var studentSchema = new Schema({
name : {type : String, required:true},
class: { type: ObjectId, ref: 'Institute.classes' },
});
var schoolSchema = new Schema({
name : {type : String, required:true},
students : [studentSchema],
classes : [classSchema]
});
var School = mongoose.model('School', schoolSchema);
Now when I am fetching a student, I want to populate the class as well. I am doing this as:
var school_id = req.params.school_id;
var student_id = req.params.student_id;
School
.findOne({'_id': school_id, 'students._id': student_id})
.populate({path: 'students.class'})
.exec(function (err, data) {
done(err, data);
});
When I do this, I get following error:
"message": "Schema hasn't been registered for model \"School.classes\".\nUse mongoose.model(name, schema)",
"name": "MissingSchemaError"
Is is possible to populate a subdocument from another subdocument?
Any help is appreciated. Thanks :)

How to populate _id field with string filed in mongodb node.js?

I have two collections user and comments.In user there is fields :
const user = mongoose.Schema({
_id :("In the form of ObjectID"),
//ObjectId("5a19086e0664e832842f2c24")
user_name :{type: String},
password : {type: String}
});
and comments collection:
const comments = mongoose.Schema({
user_id :{type: String},
//"5a19086e0664e832842f2c24" this is user's _id
comment : {type: String}
});
Now I want to know that how to populate this 2 collection with the user's _id which is in string type in comment collection.
Thankyou in advance
I think you already can use String to populate an ObjectId like this :
const user = mongoose.Schema({
user_name : {type: String},
password : {type: String}
}); // users._id will natively be an ObjectId
const comments = mongoose.Schema({
user_id : {type: String, ref:'users'}, // user_id has to be referenced with your "users" model
comment : {type: String}
});
Comment.find({}).populate('user_id').exec();
Hope it helps.
At first you need to update your schema as it requires the reference of the collection you want to populate:
const user = mongoose.Schema({
user_name: { type: String },
password: { type: String }
});
const comments = mongoose.Schema({
user_id: { type: Schema.Types.ObjectId, ref: 'User' },
comment: { type: String }
});
Note: I removed the _id field as it will be added automatically. Also take note that _id is an ObjectId not just a string (even though you can consider it as a string).
Then you can use the populate() method:
Comments.find({}).populate('user_id').exec()

Mongoose: retrieving array of ObjectIds from collection

My database has following type of documents for Categories collection.
{
"_id" : ObjectId("56716afa403743492828aa07"),
"cat_name" : "watches",
"cat_parent_id" : [
ObjectId("56716afa403743492828aa01"),
ObjectId("56716afa403743492828aa03")
]
.........
}
I first created database with Robomongo, then I'm trying to fetch data using mongoose and created following Schema.
var categorySchema = new Schema({
'cat_name' : String,
'cat_parent_id' : [{ type : mongoose.Types.ObjectId }],
.......
});
but when I'm getting the result through following callback,
Categories.find(function(err,categories){........});
the cat_parent_id array is empty.
Edit:
When I replace mongoose.Types.ObjectId with Schema.Types.ObjectId or String,It works.Can anyone provide reason for that?
You need to add reference for the ObjectId type:
var categorySchema = new Schema({
'cat_name' : String,
'cat_parent_id' : [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Categories'
}],
.......
});

How to update in mongoose?

I am new at Mongoose/nodejs and I am struggling with a simple update of an array within an array.
Here's the schema:
var County = new Schema({
_id : Schema.ObjectId,
name : String,
biggestCity : String
});
var Country = new Schema({
_id : Schema.ObjectId,
name : String,
counties : {type: [County], ref: "County"}
});
var Continent = new Schema({
_id : Schema.ObjectId,
countries : {type: [Country], ref: "Country"},
});
And here's the update code I've been trying:
var continents = mongoose.model("Continent");
var update = { "countries.counties.name": newName, "countries.counties.biggestCity": newBiggestCity };
var conditions = { "_id": countryId, "countries.name": countryName, "countries.counties.name": countyName };
var options = { multi: false };
wagers.update(conditions, update, options, function(err, numAffected) {
//callback code...
});
When doing this, the error in err says "Can't append to array using string field name 'counties'". What does this mean? What am I doing wrong?
You should define the child object as another Schema, not just as a list of some anonymous object. (Reference.)
Try defining Country as a separate Schema, nest that in Continent, then do your update.

Resources