Mongoose - 填充其他 id

Posted

技术标签:

【中文标题】Mongoose - 填充其他 id【英文标题】:Mongoose - populate with other then id 【发布时间】:2013-03-23 17:11:36 【问题描述】:

我有这两个简化的架构,我想根据 IP 地址“加入”。

var personSchema = Schema(
  name: String,
  ip: String
);

var logSchema = Schema(
  message: String,
  ip: String
);

如果 person._id 是 IP 地址,它会起作用。但这不是我的选择。

目前我已经解决了保存新日志时的问题,我搜索人员并添加对日志的引用。然后架构是这样的:

var logSchema = Schema(
  message: String,
  ip: String,
  person:  type: Schema.Types.ObjectId, ref: 'Person' 
);

我已阅读猫鼬 Populate 文档、Document#populated 和 Model.populate()。我仍然不确定这是否可能。这个例子非常简单,我在日志收集上使用了 mapReduce 和分组,因此填充对我来说非常有用。

我还阅读了Database references,在我看来,唯一的选择是基于 _id 进行填充。但它是纯 mongodb,也许还有另一种使用 mongoose 的可能性?

是否可以不基于 _id 字段填充查询?

【问题讨论】:

【参考方案1】:

MongoDB 不支持连接。所以.populate 只是进行另一个查询,因此对您来说最好的解决方案是手动进行另一个查询。

【讨论】:

您认为在每条日志记录中保存人员参考信息不如再进行一次查询? @Mr.Pohoda 这对您没有帮助,因为您仍然需要进行单独的查询(.populate 为您完成)。而且维护这样的数据库结构将更加困难。也许我不够清楚:使用.populate 进行单独查询而不是 为什么填充使用的内存比 findOne 少?我刚刚查询了 200,000 个条目(更大更容易看出差异),我的 mongod 进程在使用 populate 时从未超过 23%,但是当我使用 findOne 属性时,它几乎达到了允许的 100% 的 cpu? Mongo 3.2 确实支持聚合 $lookup 这很像一个连接【参考方案2】:

MongoDB 3.2 引入了 $lookup 聚合。您也可以将它与猫鼬一起使用。这是一个如何将它与条件 find 一起使用的示例:

  Log.aggregate(
       $match: log_property: 'value',
       $lookup: from: 'person', localField: 'ip', foreignField: 'ip', as: 'user' 
    ).exec( function (err, logs) 
      if (err) 
        next(err);
      

      res.json(logs);
    
  );

在上面的示例中,每个日志上的user 属性将使用匹配的 Person 模型文档中的人员填充

【讨论】:

以上是关于Mongoose - 填充其他 id的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose:使用 _id 以外的字段填充路径

Mongoose如何过滤填充字段

如何填充递归模式引用 Mongodb、Mongoose、Express?

Mongoose 从其他字段创建自定义 _id

为啥在 mongoose 中需要 execPopulate 方法来填充现有文档?

为啥在 mongoose 中需要 execPopulate 方法来填充现有文档?