There are a few posts here about this but not exactly what I'm after.
I have a document that contains a list of embedded documents:
{
"_id": 1234
"name": "joe"
"comments": [
{"type": "text", "content": "my content"},
{"type": "image", "content": "my_content"}
{"type": "image", "content": "my_content"}
]
}
I want to run one query that gets a set of documents then I was hoping to run a secondary query to search the "comments" list from that initial query set.
e.g p = db.people.find({"some":"condition"})
and then search the embedded docs like p.find({"type":"image"}
This obviously doesn't work. Just wondering if there's a way to do this without having to run 2 separate queries over the parent document collection again?
If you want to just find the items in a collection that satisfy a given condition and also satisfy {"type": "image"}
in the comments
array, you can do that in a single query:
p = db.people.find({"some": "condition", "comments.type": "image"})
See the dot notation page for more info.
If you do actually need the whole thing, and you're interested in specific sub-items from said result, then the best method that I can think of is just to slurp in the result into a list, and check it in Python. Do any PyMongo gurus have anything to say on this? Note that, if your dataset is large, then this is not a good idea.
p = list(db.people.find({"some": "condition"})
# A little verbose, but...
image_p = [item for item in p
if any(comment['type'] == 'image'
for comment in item['comments'])]
...
The problem using only find
with the dot notation is that you'll always get the whole document and not only the sub document.
use mongodb 2.2 to be able to use Aggregation.
look here
nb: $ElementMatch does not iteration when it is used with positional element (something.$.someattribute
), it will exit just after the first document matched, so use aggregation to get all the sub documents that matches :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With