1

I come from SQL world, and still learning to query MongoDB, and I faced this problem...

Setup:

I have a Student collection which has an array of Meetings

student: {
  meetings: [
    {time: x},
    {time: y},
    {time: z}
  ]
}

meetings array has a dynamic size, and its elements are sorted by time in asc, so the first meeting in the array would have the earliest time.

I am able to query to get all students whose first meeting begins after certain time by:

db.students.find( { "meetings.0.time": {$gt: ISODate()} } )

Question:

Now I also need to query to get all students whose LAST meeting begins before certain time. However, the following didn't work:

db.students.find( { "meetings.-1.time": {$lt: ISODate()} } )

How would you guys solve this problem?

8
  • Can't answer properly from phone. Buy you will be able to do this using the aggregation framework. Have a look on mongodb docs. Commented Mar 14, 2013 at 23:25
  • 1
    If the last time is less than the date then all the times in the array would be less than that date. maybe meets.forEach.time would work? Commented Mar 14, 2013 at 23:37
  • 2
    "LAST" by position in the array or "LAST" as in "latest"? Commented Mar 14, 2013 at 23:50
  • @sambomartin Great! Good to hear that this is possible. I'll check out the framework. Commented Mar 15, 2013 at 5:12
  • 1
    You could use aggregate command. $unwind the array and then $group to get the meeting for the max time per student. You could either $limit before Or after the group depending on what you want to return Commented Mar 16, 2013 at 12:16

1 Answer 1

1

Does this work for you?

db.student.aggregate(
  { $unwind : "$meetings" },
  { $group : { _id: "$_id", lastMeeting : { $max : "$meetings.time" }}},
  { $match: { lastMeeting : { $lt : IsoDate(...) } } 
);
Sign up to request clarification or add additional context in comments.

3 Comments

How would you change this to actually select the last element in the array, instead of using $max?
that's not possible (yet) using the aggregation framework. There are a few jira tickets relating to this jira.mongodb.org/browse/SERVER-4589 and i think this would be useful jira.mongodb.org/browse/SERVER-6074. Alternative methods I've seen would be to hold a sequence / order as an attribute in each element (meeting) - there are examples of creating a sequence on mongodb examples. If you're happy to do some processing in app you could use $slice docs.mongodb.org/manual/reference/projection/slice. Another technique would be to hold a "lastMeeting" copy next to the array
You could also use an ObjectId for each meeting too - this is unique and sequential**

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.