I have a MongoDB collection like this:
{
_id: "abc",
history:
[
{
status: 1,
reason: "confirmed"
},
{
status: 2,
reason: "accepted"
}
],
_id: "xyz",
history:
[
{
status: 2,
reason: "accepted"
},
{
status: 10,
reason: "cancelled"
}
]
}
I want to write a query in C# to return the documents whose last history item is 2 (accepted). So in my result I should not see "xyz" because its state has changed from 2, but I should see "abc" since its last status is 2. The problem is that getting the last item is not easy with MongoDB’s C# driver – or I don’t know how to.
I tried the linq’s lastOrDefault but got System.InvalidOperationException: {document}{History}.LastOrDefault().Status is not supported
error.
I know there is a workaround to get the documents first (load to memory) and then filter, but it is client side and slow (consumes lot of network). I want to do the filter on server.
2
Answers
I found a hackaround: to override the history array with the last history document, then apply the filter as if there was no array. This is possible through
Aggregate
operation$addFields
.result will be the documents with last history of 2.
Option 1) Find() -> expected to be faster
Playground1
Option 2) Aggregation
Playground2