如何更新MongoDB动态属性?

时间:2017-05-23 13:32:53

标签: mongodb

我目前正在使用具有下一个结构的动态属性模型:

{
  SKU: "Y32944EW",
  type: "shoes",
  attr: [
      { "k": "manufacturer", 
        "v": "ShoesForAll",
      },
      { "k": "color", 
        "v": "blue",
      },
      { "k": "style", 
        "v": "comfort",
      },
      { "k": "size", 
        "v": "7B"
      }
  ]
}

我需要做的是根据其他属性条件更新一些属性,例如,假设我想将颜色更新为红色,并将样式更新为运动,其中制造商是“ShoesForAll”,如果我这样做的话这样:

collection.update({"attr": { "$elemMatch" : { "k":"manufacturer", "v":"ShoesForAll" } },
  {$set: {
    attr: [ 
     { "k": "color", 
        "v": "red",
      },
      { "k": "style", 
        "v": "sport",
      },]
  }}
});

我正在丢失其他属性,例如“size”,如果我这样做:

collection.update({
    "attr": { "$elemMatch" : { "k":"manufacturer", "v":"ShoesForAll" }},
    "attr.k": "color",
    "attr.k": "style"
    }, {$set: {
            "data.$.v": "red",
            "data.$.v": "sport"  
    }})

只更新一个属性。任何人都知道如何在不丢失其他属性或不为每个属性使用一个查询的情况下更新某些属性?

由于

4 个答案:

答案 0 :(得分:1)

使用 Mongo Multi Update 首先在tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/initwifi/0.0-r0/image/etc/init.d/wifi_start.sh tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/initwifi/0.0-r0/wifi_start.sh 数组中提取所有k:[color,style]然后addToSet给定值。更新查询如下所示:

attr

答案 1 :(得分:1)

我试过forEach来解决这个问题。它目前适用于测试数据。 代码段如下: -

db.<collectionName>.find({"attr":{"k":"manufacturer","v":"ShoesForAll"}}).forEach(function(item){

item.attr.forEach(function(val){
    if(val.k == "color"){
        val.v = "red"
    }
    if(val.k == "style"){
        val.v = "sports"
    }
})
db.<collectionName>.save(item);
});

上述代码首先发现满足“制造商”条件的所有文件都是“ShoesForAll”。然后在每个文档中,我们遍历“attr”数组,更新有效字段并最终保存它。没有不必要的数据丢失。

您还提到过滤条件可以不止一个,在这种情况下使用逻辑运算符($和,$或)。举个例子: -

db.<collectionName>.find({$or: [{"attr":{"k":"manufacturer","v":"ShoesForAll"}},{"attr":{"k":"manufacturer","v":"formal"}}]}).forEach(function(item){

item.attr.forEach(function(val){
    if(val.k == "color"){
        val.v = "red"
    }
    if(val.k == "style"){
        val.v = "sports"
    }
})
db.<collectionName>.save(item);
});

将collectionName与适当位置的括号一起替换。

答案 2 :(得分:0)

根据Set Elements in Arrays上的文档,如果您的所有文档在属性中具有相同的顺序,则以下情况有效:

db.shoes.update(
    {"attr": {
        "$elemMatch" : {
            "k":"manufacturer",
            "v":"ShoesForAll" }
        }
    },
    {$set: {
        "attr.1":
             { "k": "color",
                "v": "red",
              },
        "attr.2":
              { "k": "style",
                "v": "sport",
              }
        }
    }
)

答案 3 :(得分:0)

我尝试通过定义shoe_update.js来模拟https://www.objc.io/issues/12-animations/animations-explained/,如下所示:

Node shoe_update.js

然后旋转mongod并运行.pagelinks img{ height: 10px; width: 10px; }