mongoDB:查询具有对象引用的文档

dot*_*dot 4 mongodb mongodb-3.0

我有一个小部件集合,其中包含这样的记录:

{ "_id" : ObjectId("55a6abe193819c033d4d755a"), "name" : "widget1"}
{ "_id" : ObjectId("55a6abe193819c033d4d755a"), "name" : "widget2", "loc" : ObjectId("55a69475da314d9984fc6201") }
Run Code Online (Sandbox Code Playgroud)

我还有一个位置集合,如下所示:

{ "_id" : ObjectId("55a69475da314d9984fc6201"), "abbrev" : "CAN", "description" : "Canada" }
{ "_id" : ObjectId("55a6948eda314d9984fc6202"), "abbrev" : "USA", "description" : "United States" }
{ "_id" : ObjectId("55a69496da314d9984fc6203"), "abbrev" : "MEX", "description" : "Mexico" }
Run Code Online (Sandbox Code Playgroud)

如果我想使用 Objectid 查找位于加拿大的所有小部件,我知道我可以这样做:

> db.widgets.find( { loc: ObjectId("55a69475da314d9984fc6201")})
{ "_id" : ObjectId("55a6abe193819c033d4d755a"), "name" : "widget2", "loc" : ObjectId("55a69475da314d9984fc6201") }
Run Code Online (Sandbox Code Playgroud)

但是,如果我想不使用 objectid 而使用缩写或描述来搜索位置怎么办?我该怎么做?

Ste*_*nie 6

要查询具有相关数据的两个集合,常见的方法(如 MongoDB 3.0)是_id从第一个集合中查找匹配值列表,该列表可用于$in对第二个集合的查询。

下面是一个使用mongoshell的例子:

// Find _ids for matching locations based on some criteria (eg. "abbrev")
var matches = db.locations.find({ "abbrev": "CAN"}, { _id: 1 })

// Transform matching _id values into an array
var locs = [];
matches.forEach(function(match) { locs.push(match._id) });

// Look for widgets matching the location criteria
db.widgets.find({"loc": {$in : locs} } )
Run Code Online (Sandbox Code Playgroud)

根据您使用的驱动程序和/或框架,可能有帮助函数可以更轻松地填充相关数据。这些辅助函数最终将导致多个查询,因为目前没有对连接的服务器端支持。

一些带有帮助程序的框架示例(不打算成为一个完整的列表):

您可能会注意到,我说过当前没有服务器端支持填充数据。实际上$lookup,在 MongoDB 3.1.x 开发周期(这将在 MongoDB 3.2 的最终生产发布系列中达到高潮)中,聚合框架中添加了一个新运算符。有关更多信息,请参阅:MongoDB Jira 问题跟踪器中的SERVER-19095