Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

mongodb - Pull and addtoset at the same time with mongo

I have a collection which elements can be simplified to this:

{tags : [1, 5, 8]}

where there would be at least one element in array and all of them should be different. I want to substitute one tag for another and I thought that there would not be a problem. So I came up with the following query:

db.colll.update({
  tags : 1
},{
  $pull: { tags: 1 },
  $addToSet: { tags: 2 }
}, {
  multi: true
})

Cool, so it will find all elements which has a tag that I do not need (1), remove it and add another (2) if it is not there already. The problem is that I get an error:

"Cannot update 'tags' and 'tags' at the same time"

Which basically means that I can not do pull and addtoset at the same time. Is there any other way I can do this?

Of course I can memorize all the IDs of the elements and then remove tag and add in separate queries, but this does not sound nice.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The error is pretty much what it means as you cannot act on two things of the same "path" in the same update operation. The two operators you are using do not process sequentially as you might think they do.

You can do this with as "sequential" as you can possibly get with the "bulk" operations API or other form of "bulk" update though. Within reason of course, and also in reverse:

var bulk = db.coll.initializeOrderedBulkOp();
bulk.find({ "tags": 1 }).updateOne({ "$addToSet": { "tags":  2 } });
bulk.find({ "tags": 1 }).updateOne({ "$pull": { "tags": 1 } });

bulk.execute();

Not a guarantee that nothing else will try to modify,but it is as close as you will currently get.

Also see the raw "update" command with multiple documents.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...