Kamalakannan J
Kamalakannan J

Reputation: 2998

Find a matching document based on not matching property in array of objects - MongoDB

I'm new to MongoDB or NoSQL, I have set of documents in my Rooms collection,

/* 1 */
{
    "roomId" : 1,
    "bookedFor" : [ 
        {
            "startTime" : 1000,
            "endTime" : 1100
        }, 
        {
            "startTime" : 1300,
            "endTime" : 1400
        }, 
        {
            "startTime" : 1800,
            "endTime" : 1900
        }
    ]
}

/* 2 */
{
    "roomId" : 3,
    "bookedFor" : [ 
        {
            "startTime" : 0900,
            "endTime" : 1000
        }, 
        {
            "startTime" : 1400,
            "endTime" : 1500
        }, 
        {
            "startTime" : 1300,
            "endTime" : 1400
        }
    ]
}

/* 3 */
{
    "roomId" : 2,
    "bookedFor" : [ 
        {
            "startTime" : 1000,
            "endTime" : 1100
        }, 
        {
            "startTime" : 1800,
            "endTime" : 1900
        }, 
        {
            "startTime" : 0900,
            "endTime" : 1000
        }
    ]
}

Now what I want to achieve is, I need to find a room, which should is not booked for the requesting time.

For example, If I want to book a room with startTime:1300 and endTime: 1400, it should return 3rd document alone.

P.S: Any other schema change which solve my problem is also welcomed.

Upvotes: 2

Views: 374

Answers (2)

kns
kns

Reputation: 23

I guess you can work out the logic using $lg and $gt operators combined with an $or. Finding all rooms that are not occupied, ie that do not 1) Have a booking starting during the slot 2) have a booking ending during the slot 3) Have a booking starting before and ending after the slot 4) Have a short booking during the slot

Which in this case would translate to:

db.yourcollection
    .find( {bookedFor : {
               $and:[{ 
                 {$not: {$elemMatch :{ startTime : { $gt : 1300, $lt: 1400 }},
                 {$not: {$elemMatch :{ startTime : { $gt : 1300, $lt: 1400 }},
                 {$not: {$elemMatch :{ startTime : { $lt : 1300}, endTime: {$gt: 1400 }}
                 {$not: {$elemMatch :{ startTime : { $gt : 1300}, endTime: {$lt: 1400 }}
               ]} 
    })

At least in the mongo docs, there is a similar example for elemMatch. Here is another link to negate elemMatch.

Upvotes: 0

Sede
Sede

Reputation: 61225

You can try this

db.yourcollection.find( { bookedFor : { $elemMatch : { startTime : 1300, endTime : 1400 } } } ).sort( { roomId : -1 } ).limit(1)

Upvotes: 2

Related Questions