我收集了books份文件:

{
  title: "My book",
  authors: [{id: 1, date: "2023-12-20"},{id: 2, date: "2023-12-21"}],
  authorsDetails: [{id: 2, name:"Author 2", age: 25}, {id: 1, name: "Author 1", age: 38}],
}

我需要进行聚合,结果必须返回以下结果:

{
  title: "My book",
  authors: [{id: 1, date: "2023-12-20", name: "Author 1"},{id: 2, date: "2023-12-21", name: "Author 2"}],
}

基本上我需要添加一些信息从authorsDetailsauthors.在这种情况下,只有名字.

注意:这两个数组不需要以相同的方式排序.

我试了$addFields管+$map,但还不够.我试过这个:

const pipeline = [
    //...
    {
      $addFields: {
        indices: { $range: [0, { $size: '$authors' }] },
      },
    },
    {
      $addFields: {
        admins: {
          $map: {
            input: '$indices',
            as: 'index',
            in: {
              detail: { $arrayElemAt: ['$authorsDetails', '$$index'] },
              author: { $arrayElemAt: ['$authors', '$$index'] },
            },
          },
        },
      },
    },
    //...
]

只有当数组以相同的方式排序时才有效.我还需要做另一个 map 来解决这个问题,因为我希望.

你知道怎么做吗?

推荐答案

在假设两个数组中的ID是一一对应的情况下(即,Author中的ID只会映射到AuthDetail数组中的一个条目,并且没有缺失/重复的条目),我们可以先使用$sortArray来对齐条目.然后使用$zip$mergeObjects组合数组条目.

db.collection.aggregate([
  {
    "$set": {
      "authors": {
        "$sortArray": {
          "input": "$authors",
          "sortBy": {
            "id": 1
          }
        }
      },
      "authorsDetails": {
        "$sortArray": {
          "input": "$authorsDetails",
          "sortBy": {
            "id": 1
          }
        }
      }
    }
  },
  {
    "$set": {
      "authors": {
        "$zip": {
          "inputs": [
            "$authors",
            "$authorsDetails"
          ]
        }
      }
    }
  },
  {
    "$set": {
      "authors": {
        "$map": {
          "input": "$authors",
          "as": "a",
          "in": {
            "$mergeObjects": [
              {
                $first: "$$a"
              },
              {
                $last: "$$a"
              }
            ]
          }
        }
      }
    }
  },
  {
    $unset: "authorsDetails"
  },
  {
    "$merge": {
      "into": "collection",
      "on": "_id",
      "whenMatched": "replace"
    }
  }
])

Mongo Playground

Mongodb相关问答推荐

如何使用聚合管道查找未销售但存在于产品详细信息集合中的产品的ID

在服务器上部署后端时判断??=默认判断

多键索引,性能问题

从 kubectl exec 获取返回值到 powershell 脚本

MongoDB:使用数组过滤器进行更新插入

$eq 的目的是什么

Meteor 方法与deny/allow 规则

Java MongoDB FindOne 获取最后插入的记录

将 mongoose 字符串模式类型默认值设为空白并使该字段可选

Springboot 使用 find*() 查询时出现 Mongodb 错误

Clojure 和 NoSQL 数据库

如何使用 mongodb 和 php 正确处理分页查询?

Mongodb 约定包

遍历所有 Mongo 数据库

没有参考选项的mongoose填充字段

Mongodb错误:The positional operator did not find the match needed from the query

无法将 Mongoose 连接到 Atlas

使用 mongoengine 将多文档插入到 mongodb

何时使用Singleton单例、Transient和使用 Ninject 和 MongoDB 的请求

mongoose — 判断 ObjectId 是否存在于数组中