запрос на обновление mongodb в агрегации из нескольких коллекций без группировки - PullRequest
0 голосов
/ 05 марта 2020

Могу ли я обновить указанные c поля в конкретной коллекции в соответствии с соответствующими ключами из разных коллекций, т.е. предположим, что у меня есть 3 коллекции

 **///collection 1: col1///**

    _id:ObjectId("#####7b")
    name:'name1',
    itemsBought:
   [
        {
         "_id":ObjectId("####c1"
          "itemName" : "name1",
          "itemCode" : "IT001",
          "itemQuantity" : 19,
         "itemPrediction":23
         },
        {
         "_id":ObjectId("####c2"
         "itemName" : "name2",
         "itemCode" : "IT002",
         "itemQuantity" : 79,
         "itemPrediction":69
        },
        {
        "_id":ObjectId("####c3"
        "itemName" : "name2",
         "itemCode" : "IT003",
         "itemQuantity" : 0,
         "itemPrediction":0
         },
    ]

    **///collection 1: col2///**

    {
      "itemQuantity" : 21,
      "itemCode" : "IT001",
      },
    {
      "itemQuantity" : 2,
      "itemCode" : "IT003",
      }

    **///collection 1: col3///**

    {
    "itemCode" : "IT001",
    "itemPrediction":23
    },
    {
    "itemCode" : "IT002",
    "itemPrediction":12
    },
    {
    "itemCode" : "IT003",
    "itemPrediction":7
    },

Я использую $ aggregation $ lookup для извлечения всех необходимые данные, прежде чем отправлять их во внешний интерфейс, мне нужно извлечь значения itemQuantity из col2 и itemPrediction из col3 и обновить их в col1 с помощью соответствующего itemCode. Итак, у меня есть запрос, который выбирает все данные из всех коллекций, но я не знаю, как использовать $ set для обновления значений в col1.

1 Ответ

1 голос
/ 06 марта 2020

Обходной путь : Вы можете выполнить агрегирование и сохранить результат вручную

db.col1.aggregate([
  {
    $lookup: {
      from: "col2",
      let: {
        root_itemCode: "$itemsBought.itemCode"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $in: [
                "$itemCode",
                "$$root_itemCode"
              ]
            }
          }
        }
      ],
      as: "col2"
    }
  },
  {
    $lookup: {
      from: "col3",
      let: {
        root_itemCode: "$itemsBought.itemCode"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $in: [
                "$itemCode",
                "$$root_itemCode"
              ]
            }
          }
        }
      ],
      as: "col3"
    }
  },
  {
    $addFields: {
      itemsBought: {
        $map: {
          input: "$itemsBought",
          as: "item",
          in: {
            "_id": "$$item._id",
            "itemName": "$$item.itemName",
            "itemCode": "$$item.itemCode",
            "itemQuantity": {
              $let: {
                vars: {
                  input: {
                    $arrayElemAt: [
                      {
                        $filter: {
                          input: "$col2",
                          cond: {
                            $eq: [
                              "$$item.itemCode",
                              "$$this.itemCode"
                            ]
                          }
                        }
                      },
                      0
                    ]
                  },
                  default: "$$item.itemQuantity"
                },
                in: {
                  $ifNull: [
                    "$$input.itemQuantity",
                    "$$default"
                  ]
                }
              }
            },
            "itemPrediction": {
              $let: {
                vars: {
                  input: {
                    $arrayElemAt: [
                      {
                        $filter: {
                          input: "$col3",
                          cond: {
                            $eq: [
                              "$$item.itemCode",
                              "$$this.itemCode"
                            ]
                          }
                        }
                      },
                      0
                    ]
                  },
                  default: "$$item.itemPrediction"
                },
                in: {
                  $ifNull: [
                    "$$input.itemPrediction",
                    "$$default"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $unset: [
      "col2",
      "col3"
    ]
  }
])

MongoPlayground

Пн goose

Collection1.aggregate([...], function (err, result) {

    if(err) console.log("error-agg: " + err);

    result.forEach(function(item) {
        Collection1.updateOne({_id:item._id}, {$set:item}, function (err) {
            if(err) console.log("error-saving: " + err);
        });
    });
});
...