Поле Concat int array внутри массива объекта в одно строковое поле в агрегате mongodb - PullRequest
2 голосов
/ 12 апреля 2020

Я хотел бы объединить значения полей массива 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"
}

Попытка с использованием $ lower:

 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" ошибка. Любая идея будет оценена.

Ответы [ 2 ]

0 голосов
/ 12 апреля 2020
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
        }
    }
])
0 голосов
/ 12 апреля 2020

Попробуйте следующий запрос агрегации, где идея заключается в следующем:

  • Сначала разделите поле soldPrice на 10 или требуемый делитель, используя $divide
  • Преобразование в строку и конкат, используя $toString и $concat
  • , к которому добавляется аппендер \n после каждого сокращения, удалите его из завершить с помощью $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

...