How to update MongoDB dynamic attributes?

I am currently using a dynamic attribute model with the following structure:

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

What I need to do is update some attributes based on other attribute conditions, for example, suggests that I want to update the color to red and the style to sport, where the manufacturer is “ShoesForAll”, if I do this:

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

I lose other attributes, such as "size", and if I do it like this:

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

Only one attribute is updated. Does anyone know how I can update some attributes without losing others or without using a single query for each attribute?

thank

+1
source share
4 answers

Mongo Multi Update k:[color,style], addToSet attr . :

db.runCommand({
  "update": "sku",//here sku is collection name
  "updates": [{
    "q": {
      "attr.k": "manufacturer",
      "attr.v": "ShoesForAll"
    },
    "u": {
      "$pull": {
    "attr": {
      "k": {
        "$in": ["color", "style"]
      }
    }
      }
    },
    "multi": true
  }, {
    "q": {
      "attr.k": "manufacturer",
      "attr.v": "ShoesForAll"
    },
    "u": {
      "$addToSet": {
    "attr": {
      "$each": [{
        "k": "color",
        "v": "red"
      }, {
        "k": "style",
        "v": "sport"
      }]
    }
      }
    }
  }]
})
+1

. . : -

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);
});

.

+1

The documentation for Install Elements in Arrays does the following if all of your documents have the same order in attributes:

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

I am trying to imitate the conditional upgrade approach by specifying shoe_update.js as shown below:

var MongoClient = require('mongodb').MongoClient,
    test = require('assert');

MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {

  // Get a collection
  var shoes = db.collection('shoes');

  shoes.update({
        "attr": {
            "$elemMatch": {
                "k": "manufacturer",
                "v": "ShoesForAll"
            }
        },
        "attr.k": "style"
    }, {
        $set: {
            "attr.$.v": "sport"
        },
    },
    {
        multi: true
    },
    function(err, numAffected) {
        shoes.update({
                "attr": {
                    "$elemMatch": {
                        "k": "manufacturer",
                        "v": "ShoesForAll"
                    }
                },
                "attr.k": "color"
            }, {
                $set: {
                    "attr.$.v": "red"
                }
            },
            {
                multi: true
            },
            function(err, numAffected) {
              db.close();
              }
        )
    }
  )
})

And then expand the mangon and run Node shoe_update.js.

0
source

Source: https://habr.com/ru/post/1589316/


All Articles