Pymongo 在子文档中按 _id 查找

Dio*_*lor 5 python mongodb pymongo

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

{"_id" : ObjectID("526fdde0ef501a7b0a51270e"),
  "info": "foo",
  "status": true,
  "subitems : [ {"subitem_id" : ObjectID("65sfdde0ef501a7b0a51e270"),
                 //more},
                {....}
              ],
  //more
}
Run Code Online (Sandbox Code Playgroud)

我想找到(或 find_one,没关系)带有"subitems.subitem_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) })
Run Code Online (Sandbox Code Playgroud)

然而在 mongoshell 中,这个是有效的:

find({"subitems.subitem_id" : { "$oid" : "65sfdde0ef501a7b0a51e270" } })
Run Code Online (Sandbox Code Playgroud)

Raf*_*afa 5

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

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

最后,您执行查找但不对其求值,因此您看不到任何结果。请记住 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)
Run Code Online (Sandbox Code Playgroud)

请注意,我将 oid 调整为有效的十六进制字符串。

Mongo JavaScript shell 中的相同查询。

db.col.find({"subitems.subitem_id" : new ObjectId("65cfdde0ef501a7b0a51e270")})
Run Code Online (Sandbox Code Playgroud)


nic*_*zam 3

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

蒙戈外壳:

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")} 
]}
Run Code Online (Sandbox Code Playgroud)