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)
如果 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 批量插入/更新?
| 归档时间: |
|
| 查看次数: |
7072 次 |
| 最近记录: |