mongo:数组中特定元素的更新属性

时间:2020-10-05 10:39:37

标签: node.js mongodb

我有这个收藏:

{
    "_id" : ObjectId("5ac69e90a9d1a5f3e01a5233"),
    "category": "spain",
    "products" : [ 
        {
            "label" : "uno"
        }, 
        {
            "label" : "dos"
        }, 
        {
            "label" : "tres"
        }
    ]
},
{
    "_id" : ObjectId("5ac69e90a9d1a5f3e01a5234"),
    "category": "england",
    "products" : [ 
        {
            "label" : "one"
        }, 
        {
            "label" : "two"
        }, 
        {
            "label" : "three"
        }
    ]
}

我要执行以下操作:将具有类别england的对象的标签从“一个”更新为“四个”。但是我在设计最优雅,最高性能的解决方案时遇到了一些麻烦:

第一个解决方案:我可以复制粘贴并重写整个文档,只需将其替换为四个即可 我苦苦挣扎的第二个解决方案:我想找到标签等于1的元素并将其更新为4,但是我不知道该怎么做。我不想使用像'products.O.label'这样的mongo路径索引,因为我不能保证带有标签1的产品将位于产品数组中的位置0。

预先感谢

2 个答案:

答案 0 :(得分:2)

您可以使用这个:

db.collection.updateMany(
   { category: "england" },
   { $set: { "products.$[element].label": "four" } },
   { arrayFilters: [{ "element.label": "one" }] }
)

如果您喜欢使用聚合管道,那就是这个:

db.collection.updateMany(
   { category: "england" },
   [{
      $set: {
         products: {
            $map: {
               input: "$products",
               in: {
                  $cond: {
                     if: { $eq: ["$$this.label", "one"] },
                     then: { label: "four" },
                     else: "$$this"
                  }
               }
            }
         }
      }
   }]
)

但是我认为这可能是一个过大的杀伤力。

答案 1 :(得分:0)

进一步,指的是@Wernfried Domscheit,这是使用聚合的另一种方式。

> db.catg1.find();
{ "_id" : ObjectId("5ac69e90a9d1a5f3e01a5233"), "category" : "spain", "products" : [ { "label" : "uno" }, { "label" : "dos" }, { "label" : "tres" } ] }
{ "_id" : ObjectId("5ac69e90a9d1a5f3e01a5234"), "category" : "england", "products" : [ { "label" : "four" }, { "label" : "two two" }, { "label" : "three" } ] }
> db.catg1.aggregate([
... {$unwind:"$products"},
... {$match:{category:"england",
...          "products.label":"four"
...     }
... },
... ]).forEach(function(doc){
...     print(doc._id);
...     db.catg1.update(
...       {"_id":doc._id},
...       { $set:{"products.$[element].label":"one"}},
...       {arrayFilters: [{"element.label":"four"}]}
...   );
... });
ObjectId("5ac69e90a9d1a5f3e01a5234")
> db.catg1.find();
{ "_id" : ObjectId("5ac69e90a9d1a5f3e01a5233"), "category" : "spain", "products" : [ { "label" : "uno" }, { "label" : "dos" }, { "label" : "tres" } ] }
{ "_id" : ObjectId("5ac69e90a9d1a5f3e01a5234"), "category" : "england", "products" : [ { "label" : "one" }, { "label" : "two two" }, { "label" : "three" } ] }
> db.version();
4.2.6
>