我如何使用update(..), {upsert: true})使用分片集合



假设我有一个集合,它的文档结构如下:

{
    _id: ObjectId("..."),
    shardKey: 12345,
    name: "Some User"
}

shardKey上对集合进行分片。

如果我执行findAndModify:

db.collection.findAndModify({
    query: {shardKey: 67890},
    update: {$set: {shardKey: 67890, name: "Hello, World!"}},
    upsert: true
});

如果存在shardKey等于67890的记录,则将名称设置为"Hello, World!"。如果记录不存在,则用shardKey: 67890name: "Hello, World!"创建一个新记录

好。这是预期。

然而,如果我用update(...)代替做同样的事情:

db.collection.update(
    {shardKey: 67890},
    {$set: {shardKey: 67890, name: "Hello, World!"}},
    {upsert: true}
);

MongoDB抱怨:

Can't modify shard key's value. field: shardKey: 67890

即使记录还不存在

  1. 我希望在没有记录存在的情况下使用update(...)进行干扰不会有问题。这是臭虫吗?
  2. 为什么findAndModify处理这个很好?在内部,它是否只更新已更改的字段,从而在找到记录时省略shardKey ?
  3. 还有另一个解决方案,除了findAndModify(...),不涉及使两次访问数据库(一个到find的记录,如果它已经存在,然后再一个到insertupdate取决于结果)?

这是MongoDB 2.4.0中的一个bug。请参考这张票。它已经修复了(在开发版本2.5.4中),并将在MongoDB的下一个生产版本,即2.6.0中可用。候选版本2.6.0-rc1现在已经可用,如果您的情况可以接受的话,您可以使用它。

最新更新