In the MongoDB collection I'm querying, each document represents an item at a specific time. When updating a document, a new document is created with the same item id and a new timestamp. All items have unique item ids.
To illustrate, consider this example. We start with one revision of an item:
{
_id: x,
itemId: 123,
createdOn: ISODate("2013-01-30T11:16:20.102Z"),
field1: "foo",
field2: "bar
}
After an update, we have two revisions of the item, with the same itemId and different timestamps.
[{
_id: x,
itemId: 123,
createdOn: ISODate("2013-01-30T11:16:20.102Z"),
field1: "foo",
field2: "bar"
},
{
_id: y,
itemId: 123,
createdOn: ISODate("2014-02-09T14:26:20.102Z"),
field1: "baz",
field2: "fiz"
}]
How can I find all items that in their most recent revision satisfy a certain query?
My current (wrong) approach is to first find the matching documents, then sort by timestamp, group them by itemId, and return the values from the first document in the group:
ItemModel.aggregate({ $match: { field1: "foo"} }).sort({createdOn: -1}).group(
{
_id: '$itemId', // grouping key
createdOn: {$first: '$createdOn'},
field1: {$first: '$field1'},
field2: {$first: '$field2'}
}).exec(...);
This is wrong because it matches old revisions of items. Only the latest revisions of items should match. In the example above, this approach returns item "123", while the correct result is an empty result set.