简体   繁体   English

在更新选择器中使用$ in时多个文档

[英]Upsert Multiple Documents while using $in in the update selector

I'm writing a procedure that will take an array of strings such as 我正在编写一个过程,它将采用一系列字符串,如

var mywords = ["cat", "dog", "fish"] 

and upsert them into a MongoDb collection (called the 'words' collection). 并将它们插入MongoDb集合(称为'words'集合)。 I would like to keep a count of how many times each word has been inserted into the collection. 我想要计算每个单词插入集合的次数。 It is possible that some of the words are already in the collection and some are not. 有些单词可能已经在集合中,有些则不是。

This works: 这有效:

var my_func = function(mywords) {
    //Get connection to db...

    mywords.forEach(function(word) {
        collection.update({name: word}, {$inc: {count: 1}}, {upsert: true});
    });
}

Awesome. 真棒。 So now if {name: dog, count: 3} was the only document in the collection and I run my_func(["cat", "dog", "fish"]), then the collection will now contain: 所以现在如果{name:dog,count:3}是集合中唯一的文档,我运行my_func([“cat”,“dog”,“fish”]),那么该集合现在将包含:

{name: dog, count: 4, _id: blah}
{name: cat, count: 1, _id: blah}
{name: fish, count: 1, _id: blah}

This is exactly what I want except I would like to do this all in one update, ie. 这正是我想要的,除了我想在一次更新中完成所有这些,即。 not within a forEach. 不在forEach中。 I tried this: 我试过这个:

var broken_func = function(mywords) {
    //Get connection to db...

    collection.update({name: {$in : {mywords}}, {$inc: {count: 1}}, {upsert: true, multi:true});
}

However, if I start with the same collection which only contains {name: dog, count: 3} and run my_func(["cat", "dog", "fish"]), my collection looks like this: 但是,如果我从同一个集合开始,它只包含{name:dog,count:3}并运行my_func([“cat”,“dog”,“fish”]),我的集合如下所示:

{name: dog, count: 3}
{count: 1}

I want MongoDb to match the name field of a document with any string in the mywords array and increment the count field of that document. 我希望MongoDb将文档的名称字段与mywords数组中的任何字符串相匹配,并递增该文档的count字段。 If there is no document name field equal to some string in mywords, create a document {name: "stringFrom_mywords", count:1}. 如果没有文档名称字段等于mywords中的某个字符串,请创建一个文档{name:“stringFrom_mywords”,count:1}。

Is what I want to do possible and how can I achieve the behavior I want? 我想做的是什么,我怎样才能实现我想要的行为? I feel that using forEach and doing separate updates is inefficient. 我觉得使用forEach并进行单独更新效率很低。 I happen to be using the node.js MongoDb driver if you find that information useful. 如果您发现该信息有用,我碰巧使用node.js MongoDb驱动程序。 I am aware that my problem is similar to this ruby question Upsert Multiple Records with MongoDb 我知道我的问题类似于这个红宝石问题用MongoDb Upsert Multiple Records

While you can run an update with both the upsert and multi flags, it will not have the effect that you want. 虽然您可以使用upsert和multi标志运行更新,但它不会产生您想要的效果。 You will need to run three individual upsert commands, as you are doing with your forEach example. 您需要运行三个单独的upsert命令,就像使用forEach示例一样。

If you would like to have this feature added to a future relase of MongoDB, feel free to open a Jira ticket in the SERVER project. 如果您希望将此功能添加到MongoDB的未来版本中,请随意在SERVER项目中打开Jira票证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM