0

The collection (Product) has two document:

[      
    {
            "_id" : ObjectId("5af00c72cdded465976dfc41"),
            "dates" : [{
              "start": ISODate("2018-05-01T08:21:06.152Z")
              "end": ISODate("2018-05-30T08:21:06.152Z")
            }],
            "minutes" : [ 
                {
                    "start" : 1980, //1440*1+9*60
                    "end" : 8400 // 1440*5+20*60
                }
            ]
    },
    {
            "_id" : ObjectId("5af00c72cdded465976dfc41"),
            "dates" : [],
            "minutes" : [ 
                {
                    "start" : 1980,
                    "end" : 8400
                }, 
                {
                    "start" : 9240,
                    "end" : 9720
                }
            ]
    }
]

I would like to make a criteria, that is looking for a product availiable at a specific period of time based on dates and minutes

A week is represnted in 1440 minutes, and days of week start from 0:sunday .... 6 Saturday.

My problem is when i have dates empty the document 2 is not returned, i think the problem comes from $eq. I tried $exists but it doesn't work

Document n°1 :

this product will be in store from 2018-05-01 to 2018-05-30 but only from Mondy (9am) to Friday (20pm)

Document n°2 :

1 - this product will be in store from Mondy (9am) to Friday (20pm)

 {
   "start" : 1980, //1440*1+9*60
   "end" : 8400 // 1440*5+20*60
 }

2- then in Saturday from 10 am to 18pm

{
  "start" : 9240, // 1440*6+10*60
  "end" : 9720 // 1440*6+18*60
}

My criteria is:

    const minutesInWeek = date.days() * 1440 + date.hours() * 60 + date.minutes();
    this.pModel.
        find({
            $and: [
                { minutes : {
                    $elemMatch: {
                        $or : [
                            { minutes: {$eq: [ ]} },
                            { $and: [{start: { $lte: minutesInWeek }}, {end: { $gt: minutesInWeek }} ] }
                        ]
                    }
                }},
                { dates : {
                    $elemMatch: {
                        $or : [
                            { dates: {$eq: [ ]} },
                            { $and: [{start: { $lte: new Date() }}, {end: { $gt: new Date() }} ] }
                        ]
                    }
                }}
            ]
        });;

i would really appreciate some help with this, thanks!

6
  • 1
    Try with { $size: 0 } documentation Commented May 7, 2018 at 16:32
  • @GrégoryNEUT I try this option but it doesn't work Commented May 7, 2018 at 16:37
  • Could you elaborate how "A week is represnted in 1440 minutes," ? Mongodb uses Gregorian calendar, which counts 10,080 minutes in a UTC week. Commented May 14, 2018 at 9:41
  • Also 'dates' in the first document is not a valid array. Is it an object, or an array of objects? Commented May 14, 2018 at 9:47
  • @AlexBlex Right Right it's a typo when I write the post but in my tests I use a valid the right one , its an array of objects Commented May 15, 2018 at 16:23

1 Answer 1

1

you should probably use $or first of elemMatch of dates

this.pModel.
        find({
            $and: [
                { minutes : {
                    $elemMatch: {
                        $or : [
                            { minutes: {$eq: [ ]} },
                            { $and: [{start: { $lte: minutesInWeek }}, {end: { $gt: minutesInWeek }} ] }
                        ]
                    }
                }},
                {
                    $or: [
                        {
                            $where: "this.dates.length == 0"
                        },
                        {
                            dates : {
                                $elemMatch: {
                                    $or : [
                                        { $and: [{start: { $lte: new Date() }}, {end: { $gt: new Date() }} ] }
                                    ]
                                }
                            }
                        }
                    ]
                }
            ]
        })
Sign up to request clarification or add additional context in comments.

2 Comments

this works but it return also products that do not match the first condition (dates and minutes ) :) I also get products with empty array dates
You can use this last condition inside elements match or condition

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.