Igor
Igor

Reputation: 1424

findAndModify, How to make operations on document's array search objects and change fields values

I try to find one object in document's array, and update its fields.

db.rescuemodels.findAndModify({
    query: {
        "features": {
            $elemMatch: {
                "properties.title": "W"
            }
        }
    },
    update: {
        $set: {
            "features": {
                "properties": {
                    "title": "XXX"
                }
            }
        }
    }
})

Query is fine, result is one matching element, but how to make update method change just one field in this example title? Because now it create new array or object and clean old array.

Upvotes: 0

Views: 876

Answers (2)

CurtisJD
CurtisJD

Reputation: 46

To update an individual element in the array "features" you can use the positional operator, $. Your query would look something like this...

db.rescuemodels.findAndModify({
    query: {
        "features": {
            $elemMatch: {
                "properties.title": "W"
            }
        }
    },
    update: {
        $set: {
            "features.$.properties.title": "XXX"
        }
    }
})

Upvotes: 1

Neil Lunn
Neil Lunn

Reputation: 151112

MongoDB has "Dot Notation" for this purpose, as well as the positional $ operator for referencing matched elements of an array:

  db.rescuemodels.findAndModify({
      "query": { "features.properties.title":"W" }, 
      "update": { "$set": { "features.$.properties.title":"XXX" } }
  })

Note that this only works when there is a single array present as in:

{
    "features": [
        { "properties": { "name": "A" } },
        { "properties": { "name": "W" } }
    }
}

If you are nesting arrays then MongoDB cannot match in "positional operator beyond the "outer" array only:

{
    "features": [
       { "properties": [{ "name": "A" }, { "name": "W" }] },

    ]
}

Postional matching will not work there because you cannot do features.$.properties.$.name and the matched element index would be 0 and not 1 as this refers to the outer array.

Also note that under nodejs the MongoDB driver syntax for .findAndModify() is quite different to the shell syntax. The "query" and "update" parts are separate arguments there rather than the document form as used by the shell,

Upvotes: 4

Related Questions