【问题标题】:$setUnion to merge array from multiple documents MongoDB$setUnion 从多个文档 MongoDB 中合并数组
【发布时间】:2017-07-06 15:03:49
【问题描述】:

我在一个集合中有如下文档:

{ _id : 1 , data : [7,4,0] }
{ _id : 2 , data : [4,5,6] }
{ _id : 3 , data : [6,7,8] }

我想合并两个或多个文档中的 data 数组。

我用来查找id 1 和2 的data 数组的并集的查询是:

db.coll.aggregate(
{
    $match : {
        _id: { $in: [1, 2] }
    }
},
{
    $group: { 
        _id: 0,
        s0: { $first: "$data"}, 
        s1: { $first: "$data"}
    }
},
{
    $project: {
        _id: 0,
        ans: { $setUnion: [ "$s0","$s1"]}
    }
}
).pretty()

但查询结果:

{7, 5, 0}

这似乎只是id 1 的数据。

如何实现同一个数组上两个或多个文档的并集 领域?

PS:我使用的是 MongoDB 3.4

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您可以将$unwind$group$addToSet 一起使用,

    • $match你的条件
    • $unwind解构data数组
    • $group 通过 null 并执行 $addToSet 以获取来自 data 的唯一数字
    db.coll.aggregate([
      { $match: { _id: { $in: [1, 2] } } },
      { $unwind: "$data" },
      {
        $group: {
          _id: null,
          data: { $addToSet: "$data" }
        }
      }
    ]).pretty()
    

    Playground

    【讨论】:

      【解决方案2】:

      要获得更高效的查询,请使用 $reduce 运算符来展平数组。这将允许您连接任意数量的数组,因此不仅仅是将文档 1 和 2 中的两个数组合并,这也适用于其他数组。

      考虑运行以下聚合操作:

      db.coll.aggregate([
          { "$match": { "_id": { "$in": [1, 2] } } },
          {
              "$group": {
                  "_id": 0,
                  "data": { "$push": "$data" }
              }
          },
          {
              "$project": {
                  "data": {
                      "$reduce": {
                          "input": "$data",
                          "initialValue": [],
                          "in": { "$setUnion": ["$$value", "$$this"] }
                      }
                  }
              }
          }
      ])
      

      样本输出

      {
          "_id" : 0,
          "data" : [ 0, 4, 5, 6, 7 ]
      }
      

      【讨论】:

      • 如果我想做交集,那么初始值为空,结果为空,但输入是嵌套数组
      • 如果你想要结果数组中的唯一值,你可以使用 $addToSet 而不是 $push。
      【解决方案3】:

      只需使用$last 而不是$first 来表示s1

      所以查询变成:

      db.coll.aggregate(
      {
          $match : {
              _id: { $in: [1, 2] }
          }
      },
      {
          $group: { 
              _id: 0,
              s0: { $first: "$data"}, 
              s1: { $last: "$data"}
          }
      },
      {
          $project: {
              _id: 0,
              ans: { $setUnion: [ "$s0","$s1"]}
          }
      }
      ).pretty()
      

      输出:

      { "ans" : [ 0, 4, 5, 6, 7 ] }
      

      【讨论】:

      • 谢谢!这样可行。如果我想联合两个以上的文件怎么办?如果我想合并 id 1,2 和 3 的数据,组块是什么?
      猜你喜欢
      • 2021-11-18
      • 2021-06-26
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-21
      相关资源
      最近更新 更多