0

So I have this data structure below; it is basically a calendar of events that is set for an institution.

{
    "_id" : ObjectId("58485e8b630c3106ba4af558"),
    "institutionId" : "6z66TRkvmEpCkLsKH",
    "events" : [ 
        {
            "name" : "Christmas Day",
            "date" : ISODate("2016-12-25T21:21:11.874Z"),
            "holiday" : true
        }, 
        {
            "name" : "Independence Day",
            "date" : ISODate("2016-08-04T21:21:11.874Z"),
            "holiday" : true
        }, 
        {
            "name" : "My Birthday",
            "date" : ISODate("2016-06-20T21:21:11.874Z"),
            "holiday" : false
        }
    ],
    "createdAt" : ISODate("2016-12-07T19:10:03.351Z")
}

How do I get the array of just the holidays? (where holiday = true)

[ 
  {
      "name" : "Christmas Day",
      "date" : ISODate("2016-12-25T21:21:11.874Z"),
      "holiday" : true
  }, 
  {
      "name" : "Independence Day",
      "date" : ISODate("2016-08-04T21:21:11.874Z"),
      "holiday" : true
  }
]

Is this even the right approach at storing calendar events for an institution or should I have one event per document?

Thanks!

1

1 Answer 1

2

You can do this with aggregation pretty easily, there might also be a way to do it with $elemMatch in your projection.

db.collection.aggregate([
    // Create a separate document for each element in your array
    { $unwind: '$events' },
    // Match only on the holidays
    { $match: { 'events.holiday': true } },
    // Regroup to form the array with only the matching holidays
    { $group: { _id: null, holidays: { $addToSet: '$events' }  } },
    // Return only the holidays array, and not the _id
    { $project: { _id: 0, holidays: 1 } }
]);

Returns:

{ 
    "holidays" : [ 
        { 
            "name" : "Independence Day", 
            "date" : ISODate("2016-08-04T21:21:11.874Z"), 
            "holiday" : true 
        }, 
        { 
            "name" : "Christmas Day", 
            "date" : ISODate("2016-12-25T21:21:11.874Z"), 
            "holiday" : true 
        } 
    ] 
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks man! That's what I needed!
If you're unfamiliar with the concepts of aggregation, you should try running that same command with just the unwind, then the unwind and match, then the unwind + match + group, so you can see what each stage is doing. It's pretty cool and useful stuff!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.