【问题标题】:Can you $unwind several fields at once in MongoDB Compass?你能在 MongoDB Compass 中同时 $unwind 几个字段吗?
【发布时间】:2022-07-01 17:32:38
【问题描述】:

我正在使用 MongoDB Compass 对具有公共 id 字段的几个文档进行聚合。首先我尝试了以下方法:

db.data.aggregate([
$group : {
_id : "$id",
"id" : {$first : "$id"},
"email" : {$first : "$email"},
...
}])

但是,此解决方案的问题在于,对于某些字段,我得到的是 null 而不是真实数据。我发现这是由$first 操作引起的,为了解决这个问题而不是$first,我使用了$addToSet 操作。 于是上面的代码就变成了:

 db.data.aggregate([
    $group : {
    _id : "$id",
    "id" : {$addToSet : "$id"},
    "email" : {$addToSet : "$email"},
    ...
    }])

在此之后,我没有丢失任何数据,并且一切都很好。现在的问题是,对于每个字段,对应的值是一个只有一个字符串的数组。例如,使用$addToSet 后,我得到以下结果:

{
"id" : "001",
"email" : Array(0: "asdf@gmail.com"),
"title" : Array(0: "title1")
...
}

我了解了 $unwind 操作,它可以帮助我折叠数组并获取那个元素,但是 我想知道是否有一种方法可以一次“展开”所有元素, 现在我必须为每个键值对一个一个地执行unwind 阶段,这很耗时。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework mongodb-compass


    【解决方案1】:

    不,没有。 $unwind 根据定义接收单个字段路径。

    您可以做的最简单的方法是使用arrayElemAt,假设每个字段的组只有一个值(如您的示例所示)。像这样:

    db.collection.aggregate([
      {
        $group: {
          _id: "$id",
          "id": {
            "$addToSet": "$id"
          },
          "email": {
            $addToSet: "$email"
          },
          "title": {
            $addToSet: "$title"
          }
        }
      },
      {
        $project: {
          _id: 1,
          id: {
            "$arrayElemAt": [
              "$id",
              0
            ]
          },
          email: {
            "$arrayElemAt": [
              "$email",
              0
            ]
          },
          title: {
            "$arrayElemAt": [
              "$title",
              0
            ]
          }
        }
      }
    ])
    

    Mongo Playground

    【讨论】:

      【解决方案2】:

      使用$concatArrays 然后解压

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-28
        • 2020-09-16
        • 2022-06-29
        • 1970-01-01
        • 1970-01-01
        • 2022-11-26
        • 1970-01-01
        相关资源
        最近更新 更多