4

Assuming that this one item of my database:

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

I want to find (or find_one, doesn't matter) the document(s) with "subitems.subitem_id" : xxx.

I have tried the following. All of them return an empty list.

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) })

In mongoshell this one works however:

find({"subitems.subitem_id" : { "$oid" : "65sfdde0ef501a7b0a51e270" } })
Diolor
  • 13,181
  • 30
  • 111
  • 179

2 Answers2

4

The literal 65sfdde0ef501a7b0a51e270 is not hexadecimal, hence, not a valid ObjectId.

Also, id is a Python built-in function. Avoid reseting it.

Finally, you execute a find but do not evaluate it, so you do not see any results. Remember that pymongo cursors are lazy.

Try this.

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)

Notice I adjusted oid to a valid hexadecimal string.

Same query in the Mongo JavaScript shell.

db.col.find({"subitems.subitem_id" : new ObjectId("65cfdde0ef501a7b0a51e270")})
Rafa Viotti
  • 9,998
  • 4
  • 42
  • 62
  • There are big difference between id and id(). I don't see any problems specifyin `id = 5` – nickzam Nov 01 '13 at 17:51
  • If you do `id = 5`, the `id()` built-in is effectively hidden in that scope. See http://stackoverflow.com/questions/77552. – Rafa Viotti Nov 02 '13 at 02:04
2

Double checked. Right answer is db.col.find({"subitems.subitem_id" : Objectid(id)}) Be aware that this query will return full record, not just matching part of sub-array.

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")} 
]}
nickzam
  • 793
  • 4
  • 8