使用 Mongo 聚合查询将子项与父项相关联
Relate children to parent using Mongo aggregate query
我有一个名为 assets 的集合,其中包含 2 种以上格式的文档,ParentObject 和 ChildObject。我目前正在通过两个查询将 ParentObject 与 ChildObject 相关联。这可以通过聚合查询来完成吗?
父对象
{
"_id" : {
"oid" : "ParentFooABC",
"brand" : "acme"
},
"type": "com.ParentClass",
"title": "Title1234",
"availableDate": Date,
"expirationDate": Date
}
子对象
{
"_id" : {
"oid" : "ChildFoo",
"brand" : "acme"
},
"type": "com.ChildClass",
"parentObject": "ParentFooABC",
"title": "Title1234",
"modelNumber": "8HE56",
"modelLine": "Metro",
"availableDate": Date,
"expirationDate": Date,
"IDRequired": true
}
目前我是这样过滤数据的
val parent = db.asset.find(MongoDBObject("_id.brand": MongoDBObject($eq: "acme")),MongoDBObject("type":"com.ParentClass"))
val children = db.asset.find(MongoDBObject("_id.brand": MongoDBObject($eq: "acme")),MongoDBObject("type":"com.ChildClass"), MongoDBObject("parentObject": "${parent._id.oid}"))
if(childs.nonEmpty) {
//I have confirmed this parent has a child associated and should be returned
val childModelNumbers = childs.map(child -> child.modelNumber)
val response = ResponseObject(parent, childModelNumbers)
}
我可以在聚合查询中执行此操作吗?
已更新:
Mongo版本:db版本v2.6.11
语言:Scala
驱动程序:Casbah 2.8.1
从技术上讲是的,但是您现在所做的是 mongodb 的标准做法。如果您需要经常连接数据集合,您可能应该使用 RDBMS。但是,如果您偶尔需要从 2 个单独的集合中聚合数据,则有 $lookup。通常,您会发现自己经常从另一个文档 将数据填充 到您的文档中,但这通常是文档数据库的工作方式。当你真的在寻找与 SQL JOIN
等价的东西时,使用 $lookup
不是我推荐的。这并不是真正的预期目的,您最好还是完全按照现在的做法去做,或者转向 RDBMS。
加法:
由于数据在同一个集合中,您可以使用聚合将这些数据 $group
在一起。您只需根据 _id.brand
.
对它们进行分组
一个简单的例子(在 mongodb shell):
db.asset.aggregate([
{ //start with a match to narrow down
$match: {"_id.brand": "acme"}
},
{ //group by `_id.brand`
$group: {
_id: "$_id.brand",
"parentObject": {$first: "$parentObject"},
title: {$first: "$title"},
modelNumer: {$addToSet: "$modelNumer"}, //accumulate child model # as array
modelLine: {$addToSet: "$modelLine"}, //accumulate child model line as array
availableDate: {$first: "$availableDate"},
expirationDate: {$first: "$expirationDate"}
}
}
]);
这应该 return 文档,其中所有 children 的属性都已作为数组(modelNumber,modelLine)分组到 parent 文档中。做你在上面做的事情可能会更好,如果你把 children 放入他们自己的集合而不是跟踪他们的 type 用一个type
文档中的字段。这样您就知道每个集合中的文档代表一个给定的数据结构。但是,如果您这样做,您将无法在示例中执行聚合。
我有一个名为 assets 的集合,其中包含 2 种以上格式的文档,ParentObject 和 ChildObject。我目前正在通过两个查询将 ParentObject 与 ChildObject 相关联。这可以通过聚合查询来完成吗?
父对象
{
"_id" : {
"oid" : "ParentFooABC",
"brand" : "acme"
},
"type": "com.ParentClass",
"title": "Title1234",
"availableDate": Date,
"expirationDate": Date
}
子对象
{
"_id" : {
"oid" : "ChildFoo",
"brand" : "acme"
},
"type": "com.ChildClass",
"parentObject": "ParentFooABC",
"title": "Title1234",
"modelNumber": "8HE56",
"modelLine": "Metro",
"availableDate": Date,
"expirationDate": Date,
"IDRequired": true
}
目前我是这样过滤数据的
val parent = db.asset.find(MongoDBObject("_id.brand": MongoDBObject($eq: "acme")),MongoDBObject("type":"com.ParentClass"))
val children = db.asset.find(MongoDBObject("_id.brand": MongoDBObject($eq: "acme")),MongoDBObject("type":"com.ChildClass"), MongoDBObject("parentObject": "${parent._id.oid}"))
if(childs.nonEmpty) {
//I have confirmed this parent has a child associated and should be returned
val childModelNumbers = childs.map(child -> child.modelNumber)
val response = ResponseObject(parent, childModelNumbers)
}
我可以在聚合查询中执行此操作吗?
已更新:
Mongo版本:db版本v2.6.11
语言:Scala
驱动程序:Casbah 2.8.1
从技术上讲是的,但是您现在所做的是 mongodb 的标准做法。如果您需要经常连接数据集合,您可能应该使用 RDBMS。但是,如果您偶尔需要从 2 个单独的集合中聚合数据,则有 $lookup。通常,您会发现自己经常从另一个文档 将数据填充 到您的文档中,但这通常是文档数据库的工作方式。当你真的在寻找与 SQL JOIN
等价的东西时,使用 $lookup
不是我推荐的。这并不是真正的预期目的,您最好还是完全按照现在的做法去做,或者转向 RDBMS。
加法:
由于数据在同一个集合中,您可以使用聚合将这些数据 $group
在一起。您只需根据 _id.brand
.
一个简单的例子(在 mongodb shell):
db.asset.aggregate([
{ //start with a match to narrow down
$match: {"_id.brand": "acme"}
},
{ //group by `_id.brand`
$group: {
_id: "$_id.brand",
"parentObject": {$first: "$parentObject"},
title: {$first: "$title"},
modelNumer: {$addToSet: "$modelNumer"}, //accumulate child model # as array
modelLine: {$addToSet: "$modelLine"}, //accumulate child model line as array
availableDate: {$first: "$availableDate"},
expirationDate: {$first: "$expirationDate"}
}
}
]);
这应该 return 文档,其中所有 children 的属性都已作为数组(modelNumber,modelLine)分组到 parent 文档中。做你在上面做的事情可能会更好,如果你把 children 放入他们自己的集合而不是跟踪他们的 type 用一个type
文档中的字段。这样您就知道每个集合中的文档代表一个给定的数据结构。但是,如果您这样做,您将无法在示例中执行聚合。