Find After Populate Mongoose
Solution 1:
@Jason Cust explained it pretty well already - in this situation often the best solution is to alter the schema to prevent querying Users
by properties of documents stored in separate collection.
Here's the best solution I can think of that will not force you to do that, though (because you said in the comment that you can't).
Users.find().populate({
path: 'email',
match: {
type: 'Gmail'
}
}).exec(function(err, users) {
users = users.filter(function(user) {
return user.email; // return only users with email matching 'type: "Gmail"' query
});
});
What we're doing here is populating only email
s matching additional query (match
option in .populate()
call) - otherwise email
field in Users
documents will be set to null
.
All that's left is .filter
on returned users
array, like in your original question - only with much simpler, very generic check. As you can see - either the email
is there or it isn't.
Solution 2:
Mongoose's populate
function doesn't execute directly in Mongo. Instead after the initial find
query returns a set a documents, populate
will create an array of individual find
queries on the referenced collection to execute and then merge the results back into the original documents. So essentially your find
query is attempting to use a property of the referenced document (which hasn't been fetched yet and therefore is undefined
) to filter the original result set.
In this use case it seems more appropriate to store emails as a subdocument array rather than a separate collection to achieve what you want to do. Also, as a general document store design pattern this is one of the use cases that makes sense to store an array as a subdocument: limited size and very few modifications.
Updating your schema to:
varEmailSchema = new mongoose.Schema({
type: String
});
varUserSchema = new mongoose.Schema({
name: String,
email: [EmailSchema]
});
Then the following query should work:
Users.find({'email.type':'Gmail').exec(function(err, users) {
res.json(users);
});
Post a Comment for "Find After Populate Mongoose"