MongoDB嵌入文档查询:双条件过滤后返回指定字段
Got it, let's tackle this problem step by step using your provided test data. First, let's recap what we're aiming for: from the usertest collection, we want to filter embedded documents in the objects array that meet two specific conditions, and only return a single field from those matching embedded docs.
First, let's confirm your test data
Here's the insert statement you shared (cleaned up a bit for readability):
db.usertest.insertMany([ { "username": "userA", "objects": [ { "type": "fruit", "origin": "ABC", "name": "banana" }, { "type": "fruit", "origin": "XYZ", "name": "pineapple" }, { "type": "vegetable", "origin": "XYZ", "name": "carrot" } ] }, { "username": "userB", "objects": [] } ])
Let's use a concrete example: let's say we want to find all embedded docs where type: "fruit" AND origin: "XYZ", and only get their name field. Below are two common approaches depending on your needs.
Approach 1: Aggregation Pipeline (Best for getting all matching embedded docs)
This method is flexible and will return every matching embedded document as a separate result (great if multiple docs fit your criteria):
db.usertest.aggregate([ // First, filter parent docs that have at least one matching embedded doc { $match: { "objects.type": "fruit", "objects.origin": "XYZ" } }, // Split the objects array into individual documents { $unwind: "$objects" }, // Now filter to keep only the embedded docs that meet BOTH conditions { $match: { "objects.type": "fruit", "objects.origin": "XYZ" } }, // Project only the field we care about (we can rename it for clarity too) { $project: { _id: 0, matchedName: "$objects.name" } } ])
Result:
{ "matchedName": "pineapple" }
If there were multiple matching embedded docs (e.g., another fruit from XYZ), each would show up as a separate entry in the results.
Approach 2: find() with $elemMatch (For getting the first match per parent doc)
If you want to keep the parent document structure and only pull the first matching embedded doc's field, use this:
db.usertest.find( // Filter parent docs that have at least one matching embedded doc { "objects": { $elemMatch: { type: "fruit", origin: "XYZ" } } }, // Project only the matching embedded doc's name field { _id: 0, "objects.name": { $elemMatch: { type: "fruit", origin: "XYZ" } } } )
Result:
{ "objects": [ { "name": "pineapple" } ] }
Customizing for your specific conditions
Just swap out the type and origin values in the queries to match your actual criteria. For example, if you wanted veggies from XYZ, change the type to "vegetable"—the structure stays the same.
内容的提问来源于stack exchange,提问作者Wuff

