问题
I have documents in RavenDb that may look something like this:
{ "Id": "obj/1", "Version": 1 },
{ "Id": "obj/1", "Version": 2 },
{ "Id": "obj/1", "Version": 3 },
{ "Id": "obj/1", "Version": 4 },
{ "Id": "obj/2", "Version": 1 },
{ "Id": "obj/2", "Version": 2 },
{ "Id": "obj/2", "Version": 3 },
{ "Id": "obj/3", "Version": 1 },
{ "Id": "obj/3", "Version": 3 }
I'm trying to create an index that would give me:
- The sequences "obj/1" and "obj/2", preferably grouped by Id.
- Not the sequence "obj/3", since its not yet complete
How would I do this?
回答1:
I managed to solve it. I'm not sure it is the optimal solution but it seems to work.
class SequenceIndex : AbstractIndexCreationTask<MyObject>
{
public EventSequenceIndex()
{
Map = objects => from d in docs
orderby d.Version
select new
{
Id = d.Id,
Version = d.Version
};
TransformResults = (database, results) =>
from result in results
group result by result.Id into g
where g.Select(d => d.Version + 1)
.Except(g.Select(d => d.Version))
.Count() == 1
select new
{
Id = g.Key,
Objects = g
};
}
}
With query:
var events = session.Query<MyObject, SequenceIndex>()
.As<MySequenceObjectView>()
.ToArray();
I group the documents by Id and then take all version + 1
except all version
, which for an original sequence of 1, 2, 3
will be 2, 3, 4 except 1, 2, 3
, which gives me 4
(which is why I use the Count() == 1
. But if there is a hole in the sequence, the count would be greater than 1, and therefore excluded from the results.
来源:https://stackoverflow.com/questions/12173627/finding-complete-sequences-using-a-ravendb-index