3

I have a mongo collection which stores information about products & it has an embedded array that stores its availability datewise.

{
  "product_id": "A",
  "name": "mountain bicycle",
  "cost_per_hour": "$5",
  "availability":[
    {
      "timestamp": ISODate("2018-11-19 18:30:00.000Z"),
      "available": true
    },
    {
      "timestamp": ISODate("2018-12-20 18:30:00.000Z")
      "available": true
    },
    {
      "timestamp": ISODate("2018-12-21 18:30:00.000Z")
      "available": false
    }
  ]
}

I want to list all the products that are available on all dates in a given date interval.

Example: If I query for date between ISODate("2018-11-19 18:30:00.000Z") To ISODate("2018-12-20 18:30:00.000Z") AND available: true, I should get a product with "product_id": "A", since its available on all dates between the date interval.

But If I query between ISODate("2018-11-19 18:30:00.000Z") To ISODate("2018-12-21 18:30:00.000Z") AND available: true, I should NOT get any results since the product is NOT available on all dates in the date range.

I tried using $elemMatch but that returns products that are available in at least 1 of the dates given in the interval, which I don't want.

Please guide.

1
  • 1
    I don't think its a duplicate. The post you have mentioned talks about projection, where as mine deals with querying embedded mongo array on multiple conditions & returning documents that match all the condition. Commented Nov 18, 2018 at 17:31

2 Answers 2

2

To find documents where all of an array field's elements pass a query, you can invert your query to look for the failure case (available: false), and then use $not to only return the documents where that failure case doesn't occur:

db.test.find({
  availability: {$not: {$elemMatch: {
    timestamp: {$gte: ISODate("2018-11-19 18:30:00.000Z"), 
                $lte: ISODate("2018-12-21 18:30:00.000Z")},
    available: false
  }}}
})
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @JohnnyHK. How can we do this for inversion for top-level documents i.e documents that are not a part of the array ?
-1

Folowing the documentation on:

https://docs.mongodb.com/manual/tutorial/query-array-of-documents/

at:

db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )

What you are looking for is something like:

db.StoreCollection.find( { 
         "availability": { 
              "timestamp": ISODate("2018-12-20 18:30:00.000Z")
              "available": true
          }
 })

2 Comments

Keep reading the documentation there and learn something. Specify Multiple Conditions for Array of Documents. You're query here is completely wrong. You also appear to have misread the question.
Yes I read the docs before. The above query which you have suggested will only work if the document given in query exactly matches the document structure & order present in the collection you are querying. That is not the intended result am looking at. I am querying based on only 2 fields timestamp & available field.

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.