我可以使用 mongo 中另一个集合中的数据更新集合中的列表吗?

Can I update a list in a collection using data from another collection in mongo?

我有 2 个系列,报价和库存

优惠

...
{
    "_id": "<someid>",
    "name": "Offer1",
    "items": [
        {
            "id": "1234",
            "itemName": "Apples"
        },
        {
            "id": "2345",
            "itemName": "Oranges"
        }
    ]
},
{
    "_id": "<someid>",
    "name": "Offer2",
    "items": [
        {
            "id": "1234",
            "itemName": "Apples"
        },
        {
            "id": "3456",
            "itemName": "Bananas"
        }
    ]
},
...

库存

...
{
    "_id": "<someid>",
    "id": "1234",
    "shortName": "Apples",
    "longName": "Malus domestica"
},
...

我想用库存的 longName 更新 Offers 集合中的 itemName。直接在mongodb中可以吗? 或者,在 python?

中是否有一种简单的方法可以做到这一点

这里有几种方法可以做到这一点。除了这两种方式,也许还有更好的方式。

N.B.: 我无法完全测试这些,所以您可能想尝试备份集合并验证功能。

一个"$lookup"后面跟着一个巨人"$map"。然后 "$merge".

db.Offers.aggregate([
  {
    "$lookup": {
      "from": "Inventory",
      "localField": "items.id",
      "foreignField": "id",
      "pipeline": [
        {
          "$project": {
            "_id": 0,
            "id": 1,
            "longName": 1
          }
        }
      ],
      "as": "longNames"
    }
  },
  {
    "$set": {
      "items": {
        "$map": {
          "input": "$items",
          "as": "item",
          "in": {
            "$mergeObjects": [
              "$$item",
              {
                "itemName": {
                  "$getField": {
                    "field": "longName",
                    "input": {
                      "$first": {
                        "$filter": {
                          "input": "$longNames",
                          "as": "elem",
                          "cond": { "$eq": [ "$$item.id", "$$elem.id" ] }
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  { "$unset": "longNames" },
  { "$merge": "Offers" }
])

mongoplayground.net 上试用。

"$unwind" 后跟 "$lookup",更新 "items.itemName",然后 "$group" 重新组合文档。然后 "$merge".

db.Offers.aggregate([
  { "$unwind": "$items" },
  {
    "$lookup": {
      "from": "Inventory",
      "localField": "items.id",
      "foreignField": "id",
      "as": "invItems"
    }
  },
  {
    "$set": {
      "items": {
        "$mergeObjects": [
          "$items",
          {
            "$setField": {
              "field": "itemName",
              "input": "$items",
              "value": { "$first": "$invItems.longName" }
            }
          }
        ]
      }
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "items": { "$push": "$items" },
      "name": { "$first": "$name" }
    }
  },
  { "$merge": "Offers" }
])

mongoplayground.net 上试用。