MongoDB - 在 ObjectId 上聚合 $match

Posted

技术标签:

【中文标题】MongoDB - 在 ObjectId 上聚合 $match【英文标题】:MongoDB - Aggregate $match on ObjectId 【发布时间】:2015-05-25 02:20:49 【问题描述】:

我的架构如下所示:

var mongoose = require('mongoose');

module.exports = mongoose.model('Owner',
    username: String,
    blocks: type:mongoose.Schema.Types.ObjectId, ref: 'Block',
);

我正在尝试运行查询以查看 Owner 是否引用了 Block 的 ID。 Owner 有一个 ObjectId 数组。当我运行db.owners.aggregate($match: username: 'example',$unwind: "$blocks",$project: _id : 1,blocks: 1) 时,它会返回:

 "_id" : ObjectId("550d9dc64d9dc3d026fadfc7"), "blocks" : ObjectId("550dc117dc9605ab27070af7") 
 "_id" : ObjectId("550d9dc64d9dc3d026fadfc7"), "blocks" : ObjectId("550dc123dc9605ab27070af8") 
 "_id" : ObjectId("550d9dc64d9dc3d026fadfc7"), "blocks" : ObjectId("550dc12edc9605ab27070af9") 
 "_id" : ObjectId("550d9dc64d9dc3d026fadfc7"), "blocks" : ObjectId("550dc157dc9605ab27070afa") 

如何匹配块 ID?我试过db.publishers.aggregate($match: username: 'example',$unwind: "$blocks",$project: _id : 1,blocks: 1,$match : "blocks._id" : '550dc157dc9605ab27070afa') 但这不起作用。

【问题讨论】:

【参考方案1】:

我认为您不需要聚合,您可以使用简单的find()findOne() 查询:

var Mongoose = require('mongoose');
var ObjectId = Mongoose.Types.ObjectId;

Owner.findOne( username: 'example', blocks: new ObjectId('550dc157dc9605ab27070afa') , function (err, owner) 
   ...
);

【讨论】:

这也行得通!但是我必须将它(.aggregation.find)引用为 ObjectId('550dc157dc9605ab27070afa')。在找到此链接github.com/LearnBoost/mongoose/issues/1399 后,我发现。不知道为什么我使用聚合框架。我一直在有子文档的东西上使用它。 不错!我认为 Mongoose 足够聪明,可以在字段引用其他模型时自动将字符串转换为 ObjectId,但看起来不是。我现在修改代码以在字符串上使用new ObjectId() 这对于您的用例来说是一个很好的选择,但它并没有专门回答与 ObjectId 总体匹配的问题,如果可能的话,这将非常有帮助。 @jordan 非常感谢您提供该链接:)【参考方案2】:

现在不适用于 > 3.8.31 的版本 我在那个上面浪费了无数个小时,应该早点测试之前的市长......

【讨论】:

以上是关于MongoDB - 在 ObjectId 上聚合 $match的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 查询聚合 localField ObjectId 字符串和外部字段 ObjectId

与 mongoDb 和 mongoose 聚合后填充单个 ObjectId 引用

如何在聚合期间将mongodb子集合的objectid转换为字符串

MongoDB(猫鼬)聚合计数集合中特定 ObjectID 的实例

从String到ObjectId的Spring数据MongoDb聚合查找

如何 $project ObjectId 到 mongodb 聚合中的字符串值?