使用Mongo聚合查询将子项关联到父项

时间:2016-05-02 20:33:45

标签: mongodb scala casbah

我有一个名为assets的集合,其中包含2种格式的文档,ParentObject和ChildObject。我目前正在使用两个查询将ParentObject与ChildObject相关联。可以使用聚合查询来完成吗?

ParentObject

{
    "_id" : {
        "oid" : "ParentFooABC",
        "brand" : "acme"
    },
    "type": "com.ParentClass",
    "title": "Title1234",

    "availableDate": Date,
    "expirationDate": Date
}

ChildObject

{
    "_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 version v2.6.11

语言:Scala

司机:Casbah 2.8.1

1 个答案:

答案 0 :(得分:0)

技术上是的,但是你现在正在做的是使用mongodb的标准做法。如果您需要经常加入数据集合,则可能应该使用RDBMS。但是,如果您偶尔需要汇总来自2个单独集合的数据,则会$lookup。通常,您会发现自己经常从其他文档中将数据填充到您的文档中,但这通常是文档数据库的工作方式。当你真正在寻找与SQL $lookup等价的东西时,使用JOIN并不是我推荐的。这不是真正的预期目的,你最好完全按照你现在正在做的事情或者转向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"}
   }
}
]);

这应返回所有子项的属性已作为数组(modelNumber,modelLine)分组到父文档中的文档。做上面你做的事情可能更好,如果你把孩子放到他们自己的收藏中而不是跟踪他们的类型并带有type字段,那可能会更好该文件。这样您就知道每个集合中的文档代表给定的数据结构。但是,如果您这样做,则无法在示例中执行聚合。