在mongodb中展开和分组嵌套数组对象

pop*_*opo 2 mongodb mongodb-query

在mongodb中,我具有如下数据结构:

{
    "data" : [ 
        {
            "car" : [ 
                {
                    "model" : "aaa",
                }, 
                {
                    "model" : "bbb",
                }, 
                {
                    "model" : "ccc",
                }
            ],
            "user" : {
                "id" : "123"
            }
        }
    ],
}
Run Code Online (Sandbox Code Playgroud)

我想对汽车模型领域进行分组和计数。因此,首先我尝试了如下展开方法:

.aggregate([
  { $project: {"data.car.model":1, "data.user.id":1} },
  { $unwind: {
      path: "$data.car",
      preserveNullAndEmptyArrays: true
      } },
  { $group: {
      _id: "$data.car.model",
      count: { $sum: 1 }
      } }
])
Run Code Online (Sandbox Code Playgroud)

但是结果是:

{
    "_id" : [ ["aaa", "bbb", "ccc"] ],
    "count" : 1.0
}
Run Code Online (Sandbox Code Playgroud)

因为模型没有展开,所以这不是我想要的。我希望的结果是:

[{_id:"aaa",count:1}, {_id:"bbb",count:1}, {_id:"ccc", count:1}]
Run Code Online (Sandbox Code Playgroud)

然后通过查看 嵌套在文档数组中的mongodb unwind数组,我尝试了$ project嵌套数组:

.aggregate([
  { $project: {"car":"$data.car.model", "user":"$data.user.id"} },
])
Run Code Online (Sandbox Code Playgroud)

但是结果是:

{
    "car" : [ ["aaa", "bbb", "ccc"] ],
    "user" : ["123"]
}
Run Code Online (Sandbox Code Playgroud)

如您所见,汽车和用户被嵌入到一个数组中,我仍然不能应用$ unwind方法。但是,我希望它应该像这样:

{
    "car" : ["aaa", "bbb", "ccc"],
    "user" : "123"
}
Run Code Online (Sandbox Code Playgroud)

我正在使用的mongo是3.2,我在网上搜索了很多,但没有找到答案。有可能这样做吗?

Nei*_*unn 7

您需要独立地“每个”数组:$unwind

.aggregate([
  { "$unwind": { "path": "$data", "preserveNullAndEmptyArrays": true } },
  { "$unwind": { "path": "$data.car", "preserveNullAndEmptyArrays": true } },
  { "$group": {
    "_id": "$data.car.model",
    "count": { "$sum": 1 }
  }}
])
Run Code Online (Sandbox Code Playgroud)

您实际上无法$unwind像尝试那样“伸手” 。因此,您首先要“拆开”外部阵列,然后是“内部”阵列。然后将文档弄平以进行分组。

另一种方法是$reduce在“展开”之前使用“展平数组”:

.aggregate([
  { "$project": {
    "data": {
      "$reduce": {
        "input": "$data.car",
        "initialValue": [],
        "in": {
          "$concatArrays": [ "$$value", "$$this" ]
        }
      }
    }
  }},
  { "$unwind": "$data" },
  { "$group": {
    "_id": "$data.model",
    "count": { "$sum": 1 }
  }}
])
Run Code Online (Sandbox Code Playgroud)

但这并不是真正推荐的方法,因为“投影”比使用$unwind数组中每个嵌套级别所花费的成本更高。