在MongoDB中,为什么在文档有嵌入文档时更新/查找确切文档会失败?

时间:2012-04-17 18:37:24

标签: mongodb

我正在使用pymongo作为参考。

所以,如果我有这样的文件:

{
    'name': 'bill',
    'color': 'blue',
    'subdocument': {
        'title': 'Untitled',
        'content': 'Hello World',
    }
}

如果我发现这个文件正在执行db.users.find()[0],然后将其作为参数传递给更新,Mongo将找不到要更新的文档,除非我删除子文档。将找到的文档传递给find_one也会失败,除非删除子文档。

为了优化锁定,我需要指定所有字段。如何轻松检索文档,更新文档并将原始字段作为未更改的要求传递?

3 个答案:

答案 0 :(得分:1)

由于我主要是为了乐观锁定而对此感兴趣,因此我找到了比原始尝试更好的解决方案,感谢来自MongoDB Users Group

的Scott

解决方案是使用“版本”计数器字段,仅在字段未更改时才更新。每次更新文档时,执行更新的查询都应增加计数器。 This is faster,因为不需要扫描所有字段并进行比较以进行更改。

答案 1 :(得分:0)

我相信你遇到deep bug in MongoDB。您可以看到类似的问题in this bug

嵌入式文档被比较为二进制文件,而不是作为文档进行比较。因此subdocument: {a:1,b:2}subdocument:{b:2,a:1}不同,即使它们不应该。{/ p>

请参阅this comment了解这可能是个问题的原因。

当然,第一个错误是严重的并且已经超过一年了,所以很有可能这个问题很快就会得到解决。事实上,它目前尚未安排。

答案 2 :(得分:0)

你有没有把'$ set'一词放进去?

这就是我的所作所为:

d = {
    'name': 'bill',
    'color': 'blue',
    'subdocument': {
        'title': 'Untitled',
        'content': 'Hello World',
    }
}

db.name.insert(d)
f = db.name.find_one({'name':'bill'})
print f
{u'color': u'blue', u'_id': ObjectId('4f8dbc834647df1428000002'), u'name': u'bill', u'subdocument': {u'content': u'Hello World', u'title': u'Untitled'}}

db.name.update(f, {'$set':{'name':'fred'}})

f = db.name.find_one({'name':'fred'})
print f
{u'color': u'blue', u'_id': ObjectId('4f8dbc834647df1428000002'), u'name': u'fred', u'subdocument': {u'content': u'Hello World', u'title': u'Untitled'}}