skip to Main Content

I have the following BSON :

[
  {
    arr: [
      {
        age: 24
      },
      {
        age: 55
      }
    ]
  },
  {
    arr: [
      {
        age: 12
      },
      {
        age: 14
      },
      {
        age: 17
      }
    ]
  },
  {
    arr: [
      {
        age: 11
      },
      {
        age: 13
      },
      {
        age: 20
      }
    ]
  }
]

I use the below query :

db.collection.find({
  "arr": {
    $elemMatch: {
      age: {
        $lt: 15
      }
    }
  }
},
{
  "arr.$": 1
})

and the result is :

[
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "arr": [
      {
        "age": 12
      }
    ]
  },
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "arr": [
      {
        "age": 11
      }
    ]
  }
]

My challenge is that I want if all the elements inside each arr array are less than 15 the it returns them and not when one of them are less than 15. So in this case my expectation answer is an empty array as the output as not all the elements of each array has the age value under 15.

I am not sure if I need to use $elemMatch in this case. If there is an alternative to do it please let me know. I just want to get the solution as the query result rather than JavaScript manipulations on the post processing.

By the way I used https://mongoplayground.net/ to check the dataset.

2

Answers


  1. I think you want:

    db.collection.find(
      {"arr.age": {$not: {$gt: threshold}}},
      {arr: {$first: "$arr"}} // This part is relevant if you want only the first item of the array, as seen in your example
    )
    

    See How it works on the mongoDB playground

    Login or Signup to reply.
  2. Is this what you are looking for:

    db.collection.find({
      $and: [
        {
          "arr.age": {
            $lt: 15
          }
        },
        {
          "arr.age": {
            $not: {
              $gt: 14
            }
          }
        }
      ]
    })
    

    See HERE for a working example.

    This will find only the documents that have all arr.age less than 15.

    Note: only checking for $not: { $gt: value } will return documents when you have an empty array i.e arr:[]. This will query will prevent that.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search