1

I have the following type of document where I have to find instock elements based on a given value. i.e Return all instocks where ele = 5.

{"item":"journal",
 "instock":[
    { "warehouse":"A", "ele":[2,4,5] },
    { "warehouse":"C", "ele":[8,5,2] },
    { "warehouse":"F", "ele":[3] },
    { "warehouse":"K", "ele":[2,8,4] }
    ]
}

I tried to use $elemMatch but it just produces the first element.

db.inventory.find({"item": "journal"}, {"_id": 0, "item": 0, "instock":{$elemMatch: {"ele": {$in: [5]}}} })

But it just gives:

{ "instock" : [ 
    { "warehouse" : "A", "ele" : [ 2, 4, 5 ] }
]}

And the expectation is

{ "instock" : [ 
    { "warehouse" : "A", "ele" : [ 2, 4, 5 ] },
    { "warehouse" : "C", "ele" : [ 8, 5, 2 ] }
]}

How should I get the expected result?

2 Answers 2

1

The $elemMatch or instock.$ will return first match document in find()'s projection,

You can use aggregation expression in projection from MongoDB 4.4, for your example use array $filter operator in projection,

db.collection.find({
  "item": "journal"
},
{
  instock: {
    $filter: {
      input: "$instock",
      cond: { $in: [5, "$$this.ele"] }
    }
  }
})

Playground


For the old version you can use aggregate() using above same operator.

Sign up to request clarification or add additional context in comments.

4 Comments

I think what you are suggesting is to use aggregation. Because $filter is not supporting in "find". So the working answer I created based on your answer is db.inventory.aggregate({ $match:{"item": "journal"}}, { $project: {instock: { $filter: { input: "$instock", cond: { $in: [5, "$$this. ele"] }}}}})
yes its perfect, what is the version of your mongodb?
I'm using 4.2.1
updated answer, its support in mongodb 4.4, glad you have resolved your problem with aggregate().
0

I suggest you to unwind the instock array, then filter the data, and finally if you want you can group the result by item to obtain the desired result.

Here is an exemple: solution

Comments

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.