使用MongoDb升级多个记录

jcn*_*ghm 6 ruby upsert mongodb mongomapper

我试图让MongoDB使用以下查询来插入多个记录,最终使用MongoMapper和Mongo ruby​​驱动程序.

db.foo.update({event_id: { $in: [1,2]}}, {$inc: {visit:1}}, true, true)
Run Code Online (Sandbox Code Playgroud)

如果所有记录都存在,则此方法可以正常工作,但不会为不存在的记录创建新记录.以下命令具有shell所需的效果,但从ruby驱动程序可能并不理想.

[1,2].forEach(function(id) {db.foo.update({event_id: id}, {$inc: {visit:1}}, true, true) });
Run Code Online (Sandbox Code Playgroud)

我可以循环遍历我想要在ruby中插入的每个id,但这样就需要为每个项目访问数据库.有没有办法从ruby驱动程序中只有一次数据库中的多个项目?这里的最佳做法是什么?使用mongomapper和ruby驱动程序,有没有办法在一个批处理中发送多个更新,生成如下所示的内容?

db.foo.update({event_id: 1}, {$inc: {visit:1}}, true); db.foo.update({event_id: 2}, {$inc: {visit:1}}, true);
Run Code Online (Sandbox Code Playgroud)

样本数据:

如果存在两条记录,则命令后的所需数据.

{ "_id" : ObjectId("4d6babbac0d8bb8238d02099"), "event_id" : 1, "visit" : 11 }
{ "_id" : ObjectId("4d6baf56c0d8bb8238d0209a"), "event_id" : 2, "visit" : 2 }
Run Code Online (Sandbox Code Playgroud)

如果存在两条记录,则命令后的实际数据

{ "_id" : ObjectId("4d6babbac0d8bb8238d02099"), "event_id" : 1, "visit" : 11 }
{ "_id" : ObjectId("4d6baf56c0d8bb8238d0209a"), "event_id" : 2, "visit" : 2 }
Run Code Online (Sandbox Code Playgroud)

如果仅存在具有event_id 1的记录,则命令后的所需数据.

{ "_id" : ObjectId("4d6babbac0d8bb8238d02099"), "event_id" : 1, "visit" : 2 }
{ "_id" : ObjectId("4d6baf56c0d8bb8238d0209a"), "event_id" : 2, "visit" : 1 }
Run Code Online (Sandbox Code Playgroud)

如果仅存在具有event_id 1的记录,则命令后的实际数据.

{ "_id" : ObjectId("4d6babbac0d8bb8238d02099"), "event_id" : 1, "visit" : 2 }
Run Code Online (Sandbox Code Playgroud)

Luc*_*lis 2

如果 event_id 为 1 或 2 的记录尚不存在,则不会插入任何记录,这是正确的

db.foo.update({event_id: { $in: [1,2]}}, {$inc: {visit:1}}, true, true)

这是因为objNew查询部分(请参阅http://www.mongodb.org/display/DOCS/Updating#Updating-UpsertswithModifiers)没有 field 的值event_id。因此,您将需要至少 X+1 次数据库访问,其中 X 是 event_id 的数量,以确保在特定 event_id 不存在记录时插入一条记录(+1 来自上面的查询) ,这会增加现有记录的访问计数器)。换句话说,MongoDB 如何知道您想要对 event_id 使用值 2 而不是 1?为什么不是 6?

使用 ruby​​ 进行批量插入,我认为这是可能的,如以下链接所示 - 尽管我只使用了 Java 驱动程序:使用 Mongoid 批量插入/更新?