0

I want to find all elements matching product "bat". My structure for database is as follows

[
  {
    "key": 1,
    "productArray" : [
      {
         "requirementId": 5,
         "product": "bat"
      },
      {
        "requirementId": 6,
        "product": "Pen"
      },
     ]
  },
  {
    "key": 2
  },
  {
    "key": 3,
    "productArray": [
      {
        "requirementId": 1,
        "product": "bat"
      },
      {
        "requirementId": 2,
        "product": "Pen"
      },
      {
        "requirementId": 3,
        "product": "bat"
      },
      {
        "requirementId": 4,
        "product": "bat"
      }
    ]
  }
]

I have tried the following query but this query is returning only one matching element.

db.collection.find({"key": 3}, {"productArray": {"$elemMatch": { "product": "bat"}}})

result of above query is as follows

[
 {
    "_id": ObjectId("5a934e000102030405000002"),
    "productArray": [
      {
        "product": "bat",
        "requirementId": 1
      }
    ]
 }
]

Can I get expected output for my problem is as follows using mongodb query Or should I use another approach for my case:

My expected output is as follows

[
  {
    "productArray": [
    {
      "requirementId": 1,
      "product": "bat"
    },
    {
      "requirementId": 3,
      "product": "bat"
    },
    {
      "requirementId": 4,
      "product": "bat"
    }
    ]
 }
]

1 Answer 1

1

As you found, $elemMatch but also $ are lazy operators and return the first element that matches.

You could add a pipeline in find (mongoDB 4.4+) but aggregation is better supported:

db.collection.aggregate({
  $match: {
    key: 3
  }
},
{
  $project: {
    productArray: {
      "$filter": {
        "input": "$productArray",
        "as": "p",
        "cond": {
          $eq: [
            "$$p.product",
            "bat"
          ]
        }
      }
    }
  }
})

Live version

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

6 Comments

Hello @minsky In this case I am getting all elements of an array I need only 3 of them
thanks for answer, please help more by telling how can i apply regex for matching string @minsky
@TusharKale replace "bat" for /bat/i to make it insensitive. Don't do "/bat/i", just /bat/i
I mean if i search as "bA" it should provide same result. I appreciate your answer @Minsky
@TusharKale asking how to write regular expressions is another question. The regex follows this syntax /regexHere/. This, should work though: /ba[t]/i or /b[at]/i depeding on how much flexibility you want.
|

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.