【问题标题】:mongoose find a document by reference property猫鼬通过引用属性查找文档
【发布时间】:2021-06-06 19:24:17
【问题描述】:

我有第一个模型人:

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)
    });

但我想通过给出名字而不是 Person 的 ObjectId 来找到一对,类似这样:

    Couple.find({
        'person1.firstname': "Bob"
    })
    .populate({
        path: 'person1 person2'
    })
    .exec(function (err, couple) {
        if (err)
            res.send(err);
        res.json(couple)
    });

但它总是空的......

无论如何要解决这个问题?

感谢您的任何反馈。

编辑

我刚刚实现了答案:

现在让我们看看我的 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);
    });

这行得通!感谢您的回答和修改。

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    在您的 couple 模型中,person1 是一个 ObjectID(我知道您知道),因此它显然没有属性 .firstname

    实际上最好的方法是通过用户的名字找到用户,然后用用户的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
    }
    

    只需like this exemple

    编辑:另请注意,引用必须是 _id(所以你不能用名字存储,无论如何这都是个坏主意)。

    考虑您的编辑:

    Person._id 可能是 String,引用是 ObjectId,如果是,请尝试:

    {person1: mongoose.Types.ObjectId(Person._id)}
    

    另外,您的变量是 person 而不是 Person。尝试登录person 看看你是否得到了什么。

    最后,我的代码示例真的很简单,别忘了处理错误和所有(见我上面给你的链接,它是完整的)。

    【讨论】:

    • 好的,我只是想知道是否有办法尊重 ObjectID 来获取属性。在这种情况下,我会采取你的解决方案。感谢您的帮助!
    • 您也可以考虑将对方的名字保存在这对夫妇中。甚至可以保存整个人,并删除参考。在这两种情况下,您都必须在更新此人时更新这对夫妇。只要一个人只能在一对夫妇中就可以了(因为它只会重复两次),特别是如果您还需要按人的名字、姓名、姓氏、伪等查找夫妇的话。并且会保存populate.
    • 我不想在一个人被修改的时候更新这对夫妇。这就是我在情侣中使用 ref 的原因。
    • 是的,当然,第一个答案可能是最好的选择
    • 验证答案之前的最后一点,如何在 Couple 模型中声明 Person?因为我在coupleSchema.statics.findByPersonFirstname 有问题:Person.findOne is not a function
    猜你喜欢
    • 2022-01-26
    • 2019-07-12
    • 2019-07-17
    • 2022-12-10
    • 2014-02-03
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多