猫鼬通过引用属性查找文档 [英] mongoose find a document by reference property

查看:69
本文介绍了猫鼬通过引用属性查找文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有第一个模特人:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆