0

Using Mongodb and spring data, i have a reservation collection that is storing Reservation objects. Reservation object has an Id and a version. I would like to perform a query that retrieves all the reservations with the last version. I am a bit stucked. I think I can do it with a map reduce job but I would like to do it with using Query or Aggregation. Any help would be well appreciated. thanks.

Chessman
  • 87
  • 1
  • 8
  • can you share your collection and the output you are expecting,do you want mongodb query(I can try) or some query in spring data(I don't have knowledge about springdata) – Saheed Hussain Jun 05 '14 at 16:08
  • Suppose we have this reservations collection (Id,Version): (1,0), (1,1), (1,2),(2,0),(2,1). The result of the query should be (1,2),(2,1). I am using spring data but I think that your mongodb query could be interesting. Thanks – Chessman Jun 06 '14 at 13:18

1 Answers1

0

Your question is really about implementing a versioning scheme in MongoDB.

There are a few existing resources on this topic:

It basically comes down to 2 approaches:

  1. Store historical versions embedded in the document
  2. Store historical versions in a separate "shadow" collection

What you store for these historical versions could be change deltas, or could be complete copies of the document. Each approach has its tradeoffs depending on how you need query and view the historical data.

Assuming that retrieving all reservations with the last version is a common access pattern for your application, you probably want to follow one of those approaches rather than your initial approach. Without knowing more about your application, I'd say that storing older versions to a separate "shadow" collection may be the best approach.

If there are frequent and or large updates to reservations, the embedding approach is going to to cause your document to grow over time. And assuming that the historical versions are not frequently accessed that's adding unnecessary memory and IO overhead.

Again, depending on your requirements you could also use either approach where you only store the last n revisions of the reservation.

Update -- another approach

Given your comment that you must have all reservations in the same collection, and assuming you are not able to change this constraint (that would be my first preference) here's another approach. You could implement a version numbering scheme where you would store the latest version of your reservation with a fixed version number. So for example version number 1 would always be the latest revision of the reservation. In that document you would probably want to store the total number of versions for the reservation (e.g. numVersions).

So when a reservation is updated you would need to perform 2 steps:

  1. findAndModify() the most recent copy of the reservation setting the version field to numVersions + 1.

  2. Insert your new reservation document with version = 1 which will become the new latest version of the reservation

Another similar approach would be to add some sort of "latest" tag to the latest version of the reservation rather than using the version numbering approach. This approach would be similar in that it would require a two step process when you insert a new version of a reservation, e.g. remove the "latest" tag from the current latest reservation then insert the new reservation with the "latest" tag set.

Community
  • 1
  • 1
helmy
  • 9,068
  • 3
  • 32
  • 31
  • Thank you Helmy for your response. Unfortunatly we dont know the value of the higher version for each reservation...It would have been easier... Suppose we have this reservations (Id,Version): (1,0), (1,1), (1,2),(2,0),(2,1). The result of the query should be (1,2),(2,1) – Chessman Jun 06 '14 at 06:51
  • Sorry, I misunderstood what you were asking, I will revise my answer. – helmy Jun 06 '14 at 10:44
  • thanks for your new response. In my scenario I have to store full reservations in the same collection. this is a constraint and I cannot change it. So my question is if it is possible to retrieves the last reservations using aggregation query??? – Chessman Jun 06 '14 at 13:53
  • I would either figure out a way to change/workaround/remove that constraint or go with the option of storing the reservation history in a single document. I'm looking at this from the perspective of not just what is "possible" but what approach is going to scale and perform best. There are a lot of ways to do what you're asking, but they are quite possibly going to perform very poorly and not scale well. – helmy Jun 06 '14 at 15:22
  • Thanks for your response. Anyway do you know how to perform an aggregation query in my case? – Chessman Jun 06 '14 at 15:24
  • In fact we have not version field but timeStamp. We want to to get last reservation not only now but also in past date. For example we have (1,2014/01/02),(1,2014/01/03),(1,2014/01/04),(2,2014/01/02),(2,2014/01/04). If we want the last reservations on 2014/01/05, output should be (1,2014/01/04),(2,2014/01/04) but if we want the reservations on 2014/01/03, output should be (1,2014/01/03),(2,2014/01/02). That is why I wanted to know if it is possible to do an aggregation query. I dont want to update the reservation items in my collection. – Chessman Jun 06 '14 at 15:43