将对象数组中的 int 数组字段连接到 mongodb 聚合中的一个字符串字段

Concat int array field inside an array of object into one string field in mongodb aggregate

我想将对象数组中的 int 数组字段值除以(除以 10)后连接到一个字符串字段中。

这是现有的文档格式:

{ 
  "no" : "2020921008981",  
  "date" : ISODate("2020-04-01T05:19:02.263+0000"), 
  "sale" : { 
   "soldItems" : [
       {
         "itemRefId" : "5b55ac7f0550de00210a3b24", 
         "soldPrice" : NumberInt(800), 
       },
       {
         "itemRefId" : "5b55ac7f0550de00210a3b25", 
         "soldPrice" : NumberInt(1000), 
       }
     ] 
   }
 }

预期结果:

{ 
  "no" : "2020921008981",  
  "date" : ISODate("2020-04-01T05:19:02.263+0000"),  
  "priceList" : "8.0 \n 10.0"
}

使用 $reduce 的尝试:

 priceList: {
            $reduce: {
                input: "$sale.soldItems.soldPrice",
                initialValue: "",
                in: {
                    $cond: [ { "$eq": [ { $toString: { $divide: [ "$$value", 10 ] } }, "" ] }, "$$this", { $concat: [ { $toString: { $divide: [ "$$value", 10 ] } }, "\n", "$$this" ] } ]
                }
            }
        }

但最终出现 "errmsg" : "$divide only supports numeric types, not string and double" 错误。任何想法将不胜感激。

试试下面的聚合查询,这里的思路是:

  • 首先使用 $divide
  • 将字段 soldPrice 除以 10 或所需的除数
  • 将其转换为字符串并使用 $toString and $concat
  • 进行连接
  • appender \n 在每个 reduce op 之后附加,使用 $rtrim
  • 从末尾删除它
  • 使用 $addFields
  • 创建新字段

查询:

db.collection.aggregate([
  {
    $addFields: {
      "itemPriceList": {
        $rtrim: {
          input: {
            $reduce: {
              input: "$salesOrder.purchaseItems",
              initialValue: "",
              in: {
                $concat: [
                  "$$value",
                  {
                    $toString: {
                      $divide: [
                        "$$this.soldPrice",
                        10
                      ]
                    }
                  },
                  "\n"
                ]
              }
            }
          },
          chars: "\n"
        }
      }
    }
  }
]);

结果:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "caseNumber": "2020921008981",
    "itemPriceList": "80\n100",
    "salesOrder": {
      "purchaseItems": [
        {
          "itemRefId": "5b55ac7f0550de00210a3b24",
          "soldPrice": 800
        },
        {
          "itemRefId": "5b55ac7f0550de00210a3b25",
          "soldPrice": 1000
        }
      ]
    },
    "startTime": ISODate("2016-05-18T16:00:00Z")
  }
]

Plaground Test Link

db.case.aggregate([
    {
        $set: {
            priceList: {
                $reduce: {
                    input: {
                        $map: {
                            input: "$sale.soldItems.soldPrice",
                            in: { $toString: { $divide: ["$$this", 10] } }
                        }
                    },
                    initialValue: "",
                    in: { $concat: ["$$value", "$$this", " \n "] }
                }
            }
        }
    },
    {
        $project: {
            _id: 0,
            no: 1,
            date: 1,
            priceList: 1
        }
    }
])