7
[{
  "username":"user1",
  "products":[
           {"productID":1,"itemCode":"CODE1"},
           {"productID":2,"itemCode":"CODE1"},
           {"productID":3,"itemCode":"CODE2"},
       ]
},
{
  "username":"user2",
  "products":[
           {"productID":1,"itemCode":"CODE1"},
           {"productID":2,"itemCode":"CODE2"},
       ]
}]

I want to find all the "productID" of "products" for "user1" such that "itemCode" for the product is "CODE1".

What query in mongoDB should be written to do so?

3
  • Check my updated answer Commented Sep 6, 2016 at 0:18
  • @ReubenL. thnx, Commented Sep 6, 2016 at 0:22
  • I'd do $match -> $unwind -> $replaceRoot -> $match -> $project. Commented Nov 3, 2022 at 8:17

3 Answers 3

7

If you only need to match a single condition, then the dot notation is sufficient. In Mongo shell:

db.col.find({"products.itemCode" : "CODE1", "username" : "user1"})

This will return all users with nested product objects having itemCode "CODE1".

Updated

Wasn't clear on your requirements at first but this should be it.

If you want each product as a separate entry, then you would need to use the aggregate framework. First split the entries in the array using $unwind, then use $match for your conditions.

db.col.aggregate(
  { $unwind: "$products" },
  { $match: { username: "user1", "products.itemCode": "CODE1" } }
);

response:

{ "_id" : ObjectId("57cdf9c0f7f7ecd0f7ef81b6"), "username" : "user1", "products" : { "productID" : 1, "itemCode" : "CODE1" } }
{ "_id" : ObjectId("57cdf9c0f7f7ecd0f7ef81b6"), "username" : "user1", "products" : { "productID" : 2, "itemCode" : "CODE1" } }
Sign up to request clarification or add additional context in comments.

3 Comments

This will give me the products of user2 too, which i dont want.
Ah I missed that requirement, you can just add that as an additional param.
db.col.find({"username": "user1", "products.itemCode" : "CODE1"})
1

The answer to your question is

db.col.aggregate([
   { $unwind: "$products" },
   { $match: { username: "user1", "products.itemCode": CODE1 } },
   { $project: { _id: 0, "products.productID": 1 } }
]);

In my case didn't work without [ ] tags.

Comments

0

You need multiple filter for this like below which is nothing but AND condition (assuming your collection name is collection1)

db.collection1.find({"username":"user1", "products.itemCode" : "CODE1"})

2 Comments

It will not work because finally it is going to return the whole data with "username" as "user1"
In that case you should use $unwind

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.