我有一个集合,其中包含需要拉平的平衡对象,并且该对象中的字段需要根据集合中的另一个标志重新命名-

[
  {
    "id": "1234",
    "documentType": "IV",
    "balance": {
      "total": 100,
      "openBalance": 60,
      "paid": 40
    }
  },  
  {
    "id": "9012",
    "documentType": "CM",
    "balance": {
      "total": 50,
      "applied": 0,
      "available": 50
    }
  }
]

如果documentType =="IV",那么"balance. payed"将成为$$ROOT中的"totalAmountPaid",而如果是"CM",那么"balance.applied"将重命名为appliedAmount,将"balance. availableAmount"重新命名为availableAmount,因此压平余额对象后的最终收款变成-

[
  {
    "id": "1234",
    "documentType": "IV",
    "total": 100,
    "openBalance": 60,
    "totalAmountPaid": 40
  },  
  {
    "id": "9012",
    "documentType": "CM",
    "total": 50,
    "appliedAmount": 0,
    "availableAmount": 50
  }
]

我try 像这样使用$set和$cond,但它不起作用,而且我对MongoDB命令也不是很熟悉-

db.collection.aggregate([
  {
    $set: {
      $cond: {
        if: {
          $eq: [
            "$documentType",
            "IV"
          ]
        },
        then: {
          "total": "$balance.total",
          "openBalance": "$balance.openBalance",
          "totalAmountPaid": "$balance.paid",
          "balance": "$$REMOVE"
        },
        else: {
          "$total": "$balance.total",
          "$availableAmount": "$balance.available",
          "$appliedAmount": "$balance.applied",
          "balance": "$$REMOVE"
        }
      }
    }
  }
])

推荐答案

您在$set中面临的问题是因为您试图在一个字段中创建多个字段(新对象),但您没有提供名称.

由于您要创建多个新字段,因此首先将它们创建为sub-object within one field,然后用该子对象替换原始文档会更容易.

(此外,在您的else条款中,您使用$total作为字段名称,而不是仅使用total.)

需要更改:

  1. 在查询的第一部分中,给出字段newdoc的名称,该公式包含您之前的代码.
    • 而且你不需要有"balance": "$$REMOVE",因为无论如何它都会被newdoc取代
  2. 然后将主文档的id和documentType字段与新创建的文档合并,因为您已经有additional fields in the main doc.
  3. 以及$unset不需要的balance字段和 children newdoc字段.
db.collection.aggregate([
  {
    $set: {
      newdoc: {
        $cond: {
          if: { $eq: ["$documentType", "IV"] },
          then: {
            "total": "$balance.total",
            "openBalance": "$balance.openBalance",
            "totalAmountPaid": "$balance.paid"
          },
          else: {
            "total": "$balance.total",
            "availableAmount": "$balance.available",
            "appliedAmount": "$balance.applied"
          }
        }
      }
    }
  },
  { $replaceWith: { $mergeObjects: ["$$ROOT", "$newdoc"] } },
  { $unset: ["balance", "newdoc"] }
])

Mongo Playground

(Previous Mongo Playground)

Mongodb相关问答推荐

为什么AllowDiskUse不能在$GROUP阶段的聚合管道中工作?

为什么数组长度0被认为是Mongoose中排序中最大的数字

MongoDB 聚合 - $project 和 $match 阶段未按预期工作

MongoDB 聚合 - 条件 $lookup 取决于字段是否存在

按数组mongodb中的第一个元素排序

如何使用 MindsDB 和 MQL(对于我的 MongoDB 实例)实施零样本分类?

$lookup 的参数必须是字符串

使用 EventSourcing(NodeJS、MongoDB、JSON)跨多个偶尔连接的客户端同步数据

MongoDB:按标签获取文档

如何检索 MongoDb 集合验证器规则?

什么 Javascript 库可以针对对象判断类似 MongoDB 的查询谓词?

ExpressJS & Mongoose REST API struct :最佳实践?

java.lang.IncompatibleClassChangeError:Implementing class Mongo

如何确保基于特定字段的数组中的唯一项 - mongoDB?

Flask:设置应用程序和请求特定的属性?

mongodb: UnknownError assertion src/mongo/db/server_options_helpers.cpp:355

MongoDB如何判断是否存在

带有 either or查询的mongoose findOne

如何在 Windows 上停止 mongodb 服务器?

有没有办法执行更新操作的dry run?