如何连接同一文档中的数组?

在工作室 aT

我想使用两个数组的 ID 将数据合并到一个集合中。

一个例子如下所示。

{
    "_id": ObjectId ("5976fd2eb0adec0a32fa9831"),
       "People": [
          {
            "_id": 1,      <--- ID
            "Name": "jane"
          },
          {
            "_id": 2,      <--- ID
            "Name": "Mark"
          }
       ],
       "Contents": [
          {
            "userID":  2,   <--- People ID
            "Text": "111"
          },
          {
            "userID":  1,   <--- People ID
            "Text": "Hi"
          }
       ]
}

我想制作上述文件如下。

{
    "_id": ObjectId ("5976fd2eb0adec0a32fa9831"),
    "People": [
       {
          "_id": 1,
          "Name" : "Jane"
       },
       {
          "_id": 2,
          "Name": "Mark"
       }
    ],
    "Contents": [
       {
          "userID": 2,
          "Name": "Mark",    <-- Adding
          "Text": "111",

      },
       {
          "userID": 1,
          "Name": "Jane",    <-- Adding
          "Text": "Hi",

      }
    ]
}

我尝试了各种类似$lookup$unwind事情.aggregate()但我无法得到结果。

尼尔伦

您想要$map并且$indexOfArray理想情况下:

db.collection.aggregate([
  { "$addFields": {
    "Contents": {
      "$map": {
        "input": "$Contents",
        "as": "c",
        "in": {
          "userID": "$$c.userID",
          "Name": {
            "$arrayElemAt": [
              "$People.Name",
              { "$indexOfArray": [ "$People._id", "$$c.userID" ] }
            ]
          },
          "Text": "$$c.Text"
        }
      }
    }
  }}
])

它基本上从另一个数组中$arrayElemAt获取值,用于匹配由$indexOfArray.

如果您的 MongoDB 需要回退没有该运算符的版本,那么您可以$filter改用:

db.collection.aggregate([
  { "$addFields": {
    "Contents": {
      "$map": {
        "input": "$Contents",
        "as": "c",
        "in": {
          "userID": "$$c.userID",
          "Name": {
            "$arrayElemAt": [
              { "$map": {
                "input": { 
                  "$filter": {
                    "input": "$People",
                    "as": "p",
                    "cond": { "$eq": [ "$$p._id", "$$c.userID" ] }
                  }
                },
                "as": "p",
                "in": "$$p.Name"
              }},
              0
            ]
          },
          "Text": "$$c.Text"
        }
      }
    }
  }}
])

基本上你可以$filter比较另一个数组的结果,并简单地通过索引返回第一个匹配元素0$arrayElemAt

在任何一种情况下,都不需要使用“自连接” $lookup,这只是最好避免的真正不必要的开销。

从问题中的文档中,您会得到以下信息:

/* 1 */
{
    "_id" : ObjectId("5976fd2eb0adec0a32fa9831"),
    "People" : [ 
        {
            "_id" : 1.0,
            "Name" : "jane"
        }, 
        {
            "_id" : 2.0,
            "Name" : "Mark"
        }
    ],
    "Contents" : [ 
        {
            "userID" : 2.0,
            "Name" : "Mark",
            "Text" : "111"
        }, 
        {
            "userID" : 1.0,
            "Name" : "jane",
            "Text" : "Hi"
        }
    ]
}

不过,一般来说,根本没有任何聚合运算符的理由,因为这种操作通常最好留给游标中的后处理。实际上,由于您实际上是将数据“添加”到要返回的文档中,因此最好在通过网络发送文档后进行修改。

作为上面显示为 shell 的 JavaScript 的常见习语:

db.collection.find().map( d => 
  Object.assign(
    d,
    {
      "Contents": d.Contents.map( c => 
        Object.assign(c, 
          { "Name": d.People.map(p => p.Name)[d.People.map(p => p._id).indexOf(c.userID)] }
        )
      )
    }
  )
)

产生完全相同的结果,并且通常更容易在眼睛上阅读和解释

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

同一文档中以及文档之间的Concat数组

如何在Mongodb中通过仲裁计算同一文档中两个数组的元素频率

如何多次打开同一文档?

在多个网站中引用同一文档

同一文档中的不同内容

同一文档中的img src = svg

MongoTemplate更新为同一文档在数组中设置多个对象

比较同一文档中的两个数组字段

如何在mongo中检查同一文档中的两个值?

如何在Evince中打开同一文档的多个实例?

MS WORD。如何在同一文档中创建指向图片的链接?

如何在mongo中匹配来自同一文档的字段值?

使用同一文档中的值从JSONB文档中的数组中选择项目

MongoDB-如何验证同一文档的另一个嵌套数组项中是否包含嵌套数组项?

MongoDB 聚合:用同一文档中数组中的相应对象替换 ID 数组

如何在Word文档中建立到同一文档中其他位置的超链接?

用同一文档中数组的第一个元素替换字段值

如何在MongoDB更新中将字段的值推入同一文档的另一个数组字段中

在Mongoose的同一文档中查询3个不同嵌套数组中的字段?

如何在Markdown中链接到同一文档的一部分?

MongoDB:使用同一文档中对象的属性重新塑造文档

根据同一文档中的时间戳属性更新Firestore文档上的属性

如何在同一文档中检查 6 个值中的任意 3 个

如何在 ElasticSearch 中比较同一文档中的两个字段?

比较同一文档Firestore

$ _POST与表单在同一文档上

使用同一文档中的字段减少 mongodb 中的字段

在WriteBatch中写入同一文档会导致Firebase中多次写入?

Office Word。如何在单独的窗口中打开同一文档?