Reputation: 6065
I'm using mongoose to create two models, user
and child
, that are able to relate to each other. In the mongo shell I am able to query children with a user._id
parameter and return an array of children whose admin
property is the specified user. Additionally, in my node app, I'm able to query my db of children based on their other properties such as name
. However, when I perform the following query, an empty array is returned. It should be noted that user._id
property is the string of a user that is indeed an admin. Additionally, simply changing the query parameter to name
and a corresponding value results in a successful query. Am I missing something obvious?
User.js
var UserSchema = mongoose.Schema({
username: {
type: String,
index:true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
});
Child.js
var childSchema = mongoose.Schema({
Name:{
type:String,
required:true
},
Address:{
type:String,
required: true
},
Admin : { type: Schema.Types.ObjectId, ref: 'User' },
});
Query (returns null
):
var ObjectId = require('mongoose').Types.ObjectId;
Child.find({Admin:ObjectId(user._id)},callback);
Parameters used in creation of child:
{ "Name" : "First Child", "Address" : "Sample Address", "Admin" : req.user._id }
Child Sample returned from mongo shell:
{
"_id" : ObjectId("59519c30c904d23ea2e9f58f"),
"Name" : "First Child",
"Address" : "Sample Address",
"Admin" : ObjectId("594d9e5f9d3b199b781015a3"),
"__v" : 0
}
Sample Parent:
{
"_id" : ObjectId("594d9e5f9d3b199b781015a3"),
"name" : "User",
"email" : "[email protected]",
"username" : "user",
"password" : "$2a$10$.o9k2yyUMlTpecKVkqWYr.Pg8TMCGIZrexHb3Ce//5ILpC9CDKEeS",
"__v" : 0
}
Upvotes: 0
Views: 64
Reputation: 15234
Simple typo. Schema defines field as Admin
, while you are querying with admin
. Field names are case sensitive. Code should be:
var ObjectId = require('mongoose').Types.ObjectId;
Child.find({Admin:ObjectId(user._id)},callback);
Upvotes: 1
Reputation: 151072
You seem to have a misconception of how to address property in the collection as well as not understanding that the ObjectId
type is in fact already defined in your schema, and as such mongoose will "cast" this to the defined type for you in a .find()
operation, or similar operations that are able to reference the schema.
Therefore the correct statement should be:
Child.find({ "Admin": user._id },callback);
Things you need to be aware when doing this are:
Make sure that your input's are valid and of the values you expect. It is always best to debug, by passing explicit values when you have a problem:
Child.find({ "Admin": "594d9e5f9d3b199b781015a3" },function(err, result) {
if (err) throw err; console.log(result)
})
Mongoose "pluralizes" the given model name when it determines the actual collection name to address. In particular, if you have data already defined which you then create a schema for at a later date, then you likely need to name that collection explicitly, since it may not be the same as what mongoose is choosing:
mongoose.model("Child", childSchema, "child")
In that second case, mongoose would choose "children"
by default, so the explicit name is needed to the actual collection when named differently. The common example here is a model "Person"
would actually become "people"
.
As a final note, it's a good idea to turn on "debugging" to see what Mongoose is actually doing when sending your queries/operations to MongoDB.
mongoose.set("debug", true)
Understanding these things is how you avoid future errors, and generally gain further understanding of how things work.
Upvotes: 2