猫鼬通过引用属性查找文档 [英] mongoose find a document by reference property
问题描述
我有第一个模特人:
var personSchema = new Schema({
firstname: String,
name: String
});
module.exports = mongoose.model('Person', personSchema);
还有第二对模特夫妇:
var coupleSchema = new Schema({
person1: [{ type: Schema.Types.ObjectId, ref: 'Person' }],
person2: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});
module.exports = mongoose.model('Couple', coupleSchema);
我找到一对带有对象ObjectId的夫妇:
Couple.find({
'person1': req.params.objectid
})
.populate({
path: 'person1 person2'
})
.exec(function (err, couple) {
if (err)
res.send(err);
res.json(couple)
});
但是我想通过给一个名字而不是一个人的ObjectId来找到一对,就像这样:
Couple.find({
'person1.firstname': "Bob"
})
.populate({
path: 'person1 person2'
})
.exec(function (err, couple) {
if (err)
res.send(err);
res.json(couple)
});
但是它总是空的...
有解决办法吗?
谢谢您的反馈.
编辑
我刚刚实现了答案:
现在让我们看看我的情侣模型:
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);
这种用法:
Couple.findByUsername(req.params.username, function (err, couple) {
if(err)
res.send(err);
res.json(couple);
});
那行得通!谢谢您的回答和修改.
在您的couple
模型中,person1
是一个ObjectID(我知道您知道),因此它显然没有属性.firstname
. /p>
实际上,实现此目的的最佳方法是通过名字来找到用户,然后使用用户的id
查询该对夫妇.
此方法可以(应该)作为静态方法(简化的代码示例)放在couple
模型中:
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
}
还要注意,引用必须是_id
(因此您不能使用名字存储,反正这是个坏主意).
考虑您的修改:
Person._id
可能是String
,引用是ObjectId
,如果是这样,请尝试:
{person1: mongoose.Types.ObjectId(Person._id)}
此外,您的变量是person
而不是Person
.尝试登录person
看看是否有帮助.
最后,我的代码示例非常简单,不要忘了处理错误和所有错误(请参阅上面我给您的链接,它是完整的).
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.
EDIT
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.
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 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).
Considering your edit:
Person._id
is maybe a String
and the reference is an ObjectId
, if so, try:
{person1: mongoose.Types.ObjectId(Person._id)}
Also, you 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).
这篇关于猫鼬通过引用属性查找文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!