0

I am making a new application in MongoDB, and I have found that the Document-oriented modeling style fits all of my models quite well.

However, my one stumbling block is a "CheckIn" style action. Users can check in at a location, and I need to store the following for each check in:

  • User ID
  • Place ID
  • Date of checkin

Now normally I'd just store this under the User document as an embed, but I frequently will want to ask the following questions:

  • Where are all places a user has checked in?
  • What are all checkins that have happened at a certain place?
  • All checkins for a given user-place combo?
  • All checkins for a user or place in a specific time frame?

In a relational database this screams has-many through, but in Mongo that's not such an obvious relation. Should I just make Checkin a top-level object and take the performance hit of the join-style query? I might also need to add fields to the checkin object over time, so I want to keep the solution flexible.

Sam Stern
  • 24,624
  • 13
  • 93
  • 124

1 Answers1

2

Yes. If you embed checkins as an array within the user document, then the query "10 most recent checkins for a place" will be nearly impossible. Same if you embed in place, "10 most recent checkins for user" will be very hard. So make checkins its own collection.

If you index both userid and placeid in the checkins collection your queries should be fast enough. For example, to find user Jesse's most recent checkins, look up users by name to find Jesse's _id, and query checkins for that userid. It's just two queries. Same for a place's most recent checkins.

If you query the most recent checkins for a place and want the users' names, you can first query the checkins collection to get the list of userids, and use an $in query to get all the user documents. Again, it's just two queries, and both are fully indexed if you create the proper indexes.

A. Jesse Jiryu Davis
  • 23,641
  • 4
  • 57
  • 70