假设我有一个文档结构如下的集合:
{
_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: 67890
和name: "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
即使记录还没有存在。
update(...)
进行upsert并不会成为问题。这是一个错误吗?findAndModify
处理这个罚款?在内部,它是否只更新已更改的字段,从而在找到记录时省略shardKey
?findAndModify(...)
之外是否还有其他解决方案,并不涉及两次访问数据库(如果记录已经存在,则一次到find
,然后还有一个取决于结果,insert
或update
?答案 0 :(得分:1)
这是MongoDB 2.4.0中的一个错误。请参阅此ticket。它已被修复(在开发版本2.5.4中),并将在MongoDB的下一个生产版本中提供,即2.6.0。发布候选版本2.6.0-rc1现已上市,如果在您的情况下可以接受,您可以使用它。