Reputation: 1878
I have these documents in a collection:
[{
"_id" : ObjectId("57496afadc964de30a8084a1"),
"name" : "MongoDB: The Definitive Guide",
"tags" : [ "IT", "SQL" ]
},{
"_id" : ObjectId("57496afadc964de30a8084a2"),
"name" : "MongoDB Applied Design Patterns",
"tags" : [ "SQL", "MongoDB" ]
}]
I need to rename all "SQL" tags to "NoSQL" in all documents. I can do it by first adding the new tag-name, and then removing the one that needs updating:
db.getCollection('Book').update(
{ tags: 'SQL' },
{ '$push': { tags: 'NoSQL' } },
{ multi: true })
db.getCollection('Book').update(
{ tags: 'SQL' },
{ '$pull': { tags: 'SQL' } },
{ multi: true })
But this requires two separate queries.
How can I achieve this with a singe statement?
Upvotes: 3
Views: 426
Reputation: 7920
You can use $ operator
to update a particular element in a document, and using multi
option you will update all matching documents.
db.getCollection('Book').update(
{ tags: 'SQL' },
{ '$set': { "tags.$": 'NoSQL' } },
{ multi: true })
Beware that this will only update the first matched element in a document. So assuming you may have duplicate tags in a document such as {tags: ["SQL", "Java", "SQL"]}
, the above query will only update the first element. You can use $addToSet
rather than $push
to guarantee that there won't be duplicate tags in your documents.
Upvotes: 2
Reputation: 61225
You are using the wrong operators. You need to use the $set
operator and the $
positional update operator. Also you should be using updateMany()
because update()
is deprecated in official language drivers.
db.getCollection('Book').updateMany(
{ 'tags': 'SQL' },
{ '$set': { 'tags.$': 'NoSQL' } }
)
Upvotes: 4