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 的实例