Python Pymongo在子文档中按_id查找

Python Pymongo在子文档中按_id查找,python,mongodb,pymongo,Python,Mongodb,Pymongo,假设我的数据库中的这一项: {"_id" : ObjectID("526fdde0ef501a7b0a51270e"), "info": "foo", "status": true, "subitems : [ {"subitem_id" : ObjectID("65sfdde0ef501a7b0a51e270"), //more}, {....} ], //more } 我想查找(或

假设我的数据库中的这一项:

{"_id" : ObjectID("526fdde0ef501a7b0a51270e"),
  "info": "foo",
  "status": true,
  "subitems : [ {"subitem_id" : ObjectID("65sfdde0ef501a7b0a51e270"),
                 //more},
                {....}
              ],
  //more
}
我想查找(或查找一个,无所谓)带有
“subitems.subitem\u id”:xxx
的文档

我试过以下方法。它们都返回一个空列表

from pymongo import MongoClient,errors
from bson.objectid import ObjectId

id = '65sfdde0ef501a7b0a51e270'

db.col.find({"subitems.subitem_id" : id } ) #obviously wrong
db.col.find({"subitems.subitem_id" : Objectid(id) })
db.col.find({"subitems.subitem_id" : {"$oid":id} })
db.col.find({"subitems.subitem_id.$oid" : id })
db.col.find({"subitems.$.subitem_id" : Objectid(id) })
然而,在mongoshell,这一点很有效:

find({"subitems.subitem_id" : { "$oid" : "65sfdde0ef501a7b0a51e270" } })

仔细检查。正确答案是
db.col.find({“subitems.subitem_id”:Objectid(id)})
请注意,此查询将返回完整记录,而不仅仅是匹配子数组的一部分

Mongo shell:

a = ObjectId("5273e7d989800e7f4959526a")
db.m.insert({"subitems": [{"subitem_id":a},
                          {"subitem_id":ObjectId()}]})
db.m.insert({"subitems": [{"subitem_id":ObjectId()},
                          {"subitem_id":ObjectId()}]})
db.m.find({"subitems.subitem_id" : a })

>>> { "_id" : ObjectId("5273e8e189800e7f4959526d"), 
"subitems" : 
[
 {"subitem_id" : ObjectId("5273e7d989800e7f4959526a") },    
 {"subitem_id" : ObjectId("5273e8e189800e7f4959526c")} 
]}

文字
65sfdde0ef501a7b0a51e270
不是十六进制,因此不是有效的ObjectId

另外,
id
是Python的内置函数。避免重置它

最后,您执行了一个find,但没有对其求值,因此看不到任何结果。请记住,pymongo游标是懒惰的

试试这个

from pymongo import MongoClient
from bson.objectid import ObjectId

db = MongoClient().database
oid = '65cfdde0ef501a7b0a51e270'

x = db.col.find({"subitems.subitem_id" : ObjectId(oid)})

print list(x)
注意,我将oid调整为有效的十六进制字符串

Mongo JavaScript shell中的相同查询

db.col.find({"subitems.subitem_id" : new ObjectId("65cfdde0ef501a7b0a51e270")})

当给出额外的解释时,答案的质量得到了很大的提高。改进并添加了示例。注意这个答案和问题中的印刷错误。在您看到Objectid或Objectid的地方,它应该是Objectid。大写字母I和小写字母d。在JavaScript和Python中。答案中没有错误。它是在Mongo shell中测试的,复制粘贴在这里。修正了问题中的打字错误。id和id()之间有很大区别。我看不出有任何问题。如果您这样做,
id=5
,则内置的
id()
实际上隐藏在该范围内。看见