使用pymongo驱动程序裸连接python到mongodb,为什么使用ObjectId实例作为嵌入文档的键会引发InvalidDocument错误?
我试图使用objectids链接文档,似乎无法理解为什么我想将它们转换为字符串时,为驱动程序自动创建的是 ObjectId
实例 .
item = collection.find({'x':'foo'})
item['otherstuff'] = {pymongo.objectid.ObjectId() : 'data about this link'}
collection.update({'x':'foo'}, item)
bson.errors.InvalidDocument: documents must have only string keys, key was ObjectId('4f0b5d4e764df61c67000000')
在实践中,链接的id表示包含问题的文档,例如,字典中的键值为“otherstuff”,表示该单个文档对该特定问题的响应 .
是否有一个理由应用这样的objectids将不会编码成bson然后失败?是否无法将ObjectIds嵌套在这样的文档中进行交叉引用?我误解了他们的目的吗?
1 回答
BSON spec指示键必须是字符串,因此PyMongo将此作为无效文档拒绝(并且无论在哪个级别将ObjectId用作键,无论是在顶级还是在嵌入式文档中)都是正确的 . 除了其他原因之外,这是必要的,以便查询语言可以是明确的 . 想象一下,你有这份文件(并且它是一份有效的BSON文件):
然后你尝试查询:
这应该归还这份文件吗?该字符串是否应自动装入ObjectId? Mongo如何知道什么时候可以自动装箱,以及如何在像这个文件的情况下消除歧义?
您的问题的一个可能的替代解决方案是拥有一系列嵌入式文档,如:
这是有效的BSON,并且还可以更有效地索引 . 如果在
answers
上添加索引,则可以有效地搜索这些子文档上的完全匹配项;如果你在answers.answer_id
上添加索引,那么你可以通过ObjectId有效地搜索你正在寻找的答案(等等) .