This question already has an answer here:
-
How to Update Multiple Array Elements in mongodb
10 answers
I have objects like this
{
"_id" : ObjectId("5742be02289512cf98bf63e3"),
"name" : "test1",
"name" : "test1",
"attributes" : [
{
"name" : "x",
"color" : "0xd79c9c",
"_id" : ObjectId("5742be02289512cf98bf63e8")
},
{
"name" : "y",
"color" : "0xd79c9c",
"_id" : ObjectId("5742be02289512cf98bf63e7")
},
{
"name" : "z",
"color" : "0xd79c9c",
"_id" : ObjectId("5742be02289512cf98bf63e6")
}
],
"__v" : 6
}
And I want to update all documents, and set for each attribute new field.
So I want to run single query, to update all documents at once. I think, this query will do it
db.spaces.update({}, { $set: { "attributes.0.weight": 2 } }, {multi: true})
But when I run this query, I get an error.
"code" : 16837,
"errmsg" : "The positional operator did not find the
match needed from the query. Unexpanded update: attributes.$.weight"
So I cant understand why.
Please help
You need to include the array field as part of the query document in order to use the positional operator
.
For example, if you want to update the first array element i.e. with { "attributes.name": "x" }
then you could follow the pattern:
db.spaces.update(
{ "attributes.name": "x" }, // <-- the array field must appear as part of the query document.
{ "$set": { "attributes.$.weight": 2 } },
{ "multi": true }
)
For the newer MongoDB versions 3.2.X
, you could use the updateMany()
method to update multiple documents within the collection based on the filter above.
The positional operator needs a match, from the match part of your update query.
for example:
db.spaces.update({ "attributes.name": "x" }, { $set: { "attributes.0.weight": 2 } }, {multi: true})
here the first parameter for update operation will match the array attributes
where any element has a property name=="x"
, for any eleent that matches the condition the position operator can be used to update it.
So, because name='x'
, in this case the first matching element would be,
{
"name" : "x",
"color" : "0xd79c9c",
"_id" : ObjectId("5742be02289512cf98bf63e8")
},
and it will get updated.
Now from your question I understand you want to update the document in a way that in each document your first element, attribute
gets a new value for weight=2
.
you can do something like
db.spaces.update({ "attributes.name": { $regex: /^(?=[\S\s]{10,8000})[\S\s]*$/ } }, { $set: { "attributes.0.weight": 2 } }, {multi: true})
What we do here is match all element in array attribute. and the we use the positional operator to update the first element of that array