如何将更新(...,{upsert:true})与分片集合一起使用?

时间:2014-03-18 13:52:21

标签: mongodb

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

{
    _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(...)进行upsert并不会成为问题。这是一个错误吗?
  2. 为什么findAndModify处理这个罚款?在内部,它是否只更新已更改的字段,从而在找到记录时省略shardKey
  3. findAndModify(...)之外是否还有其他解决方案,并不涉及两次访问数据库(如果记录已经存在,则一次到find,然后还有一个取决于结果,insertupdate

1 个答案:

答案 0 :(得分:1)

这是MongoDB 2.4.0中的一个错误。请参阅此ticket。它已被修复(在开发版本2.5.4中),并将在MongoDB的下一个生产版本中提供,即2.6.0。发布候选版本2.6.0-rc1现已上市,如果在您的情况下可以接受,您可以使用它。