I have a first model Person:
var personSchema = new Schema({
firstname: String,
name: String
});
module.exports = mongoose.model('Person', personSchema);
And a second model Couple:
var coupleSchema = new Schema({
person1: [{ type: Schema.Types.ObjectId, ref: 'Person' }],
person2: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});
module.exports = mongoose.model('Couple', coupleSchema);
I find a couple with a person ObjectId:
Couple.find({
'person1': req.params.objectid
})
.populate({
path: 'person1 person2'
})
.exec(function (err, couple) {
if (err)
res.send(err);
res.json(couple)
});
But I would like to find a couple by giving a firstname and not an ObjectId of a Person, something like that:
Couple.find({
'person1.firstname': "Bob"
})
.populate({
path: 'person1 person2'
})
.exec(function (err, couple) {
if (err)
res.send(err);
res.json(couple)
});
But it is always empty...
Anyway to solve this?
Thank you for any feedback.
I just implemented the answer:
Let's see my Couple model now:
var Person = require('mongoose').model('Person');
var coupleSchema = new Schema({
person1 : [{ type: Schema.Types.ObjectId, ref: 'Person' }],
person2 : [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});
coupleSchema.statics.findByUsername = function (username, callback) {
var query = this.findOne()
Person.findOne({'firstname': username}, function (error, person) {
query.where(
{person1: person._id}
).exec(callback);
})
return query
}
module.exports = mongoose.model('Couple', coupleSchema);
With this usage:
Couple.findByUsername(req.params.username, function (err, couple) {
if(err)
res.send(err);
res.json(couple);
});
That works! Thank you for your answer and edits.
The ref option is what tells Mongoose which model to use during population, in our case the Story model. All _id s we store here must be document _id s from the Story model. Note: ObjectId , Number , String , and Buffer are valid for use as refs.
Return value findById returns the document where the _id field matches the specified id . If the document is not found, the function returns null .
The __v field is called the version key. It describes the internal revision of a document.
$gte selects the documents where the value of the field is greater than or equal to (i.e. >= ) a specified value (e.g. value .)
In your couple
model, person1
is an ObjectID (I know you know it), so it has no obviously no property .firstname
.
Actually the best way to achieve this, is to find the user by it's first name, and then query the couple, with the id
of the user.
This method could/should stand in the couple
model as a static method (simplified code sample):
couple.statics.findByPersonFirstname = function (firstname, callback) {
var query = this.findOne()
Person.findOne({firstname: firstname}, function (error, person) {
query.where($or: [
{person1: person._id},
{person1: person._id}
]).exec(callback);
})
return query
}
Just like this exemple.
EDIT: Also note that the ref must be the _id
(so you couldn't store with the first name, that would be a bad idea anyway).
Person._id
is maybe a String
and the reference is an ObjectId
, if so, try:
{person1: mongoose.Types.ObjectId(Person._id)}
Also, your variable is person
and not Person
. Try to log person
to see if you get something.
Finally, my code sample is really simple, don't forget to handle errors and all (see the link I gave you above, which is complete).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With