How to get document (in separate transaction) after QueryIndex
ovekaaven opened this issue · 3 comments
I have an index, and I want a background job to go through each document one by one and process each in a separate transaction. Thus, Query is not useful since it would not use the transaction I want, but I can't quite see how to get DocumentId from the QueryIndex result, either. I'm trying to do something like
var query = await session.QueryIndex<JobIndex>(x => x.Pending).ListAsync();
foreach (var index in query) {
await session.BeginTransactionAsync();
var job = session.GetAsync<Job>(index.DocumentId);
// do stuff
await session.CommitAsync();
}
Is this possible? The "Id" field in the MapIndex class seems to be unrelated to the document ID.
We could probably add DocumentId
to IIndex
and then also populate it when doing index queries since it's in the table.
In the meantime you can create your own SQL query to list this index.
Then to have distinct transactions you can create a new session each time. The other option is to call session.SaveChangesAsync
which will dispose the transaction, so the next call to BeginTransactionAsync
will create a new one (and open a new connection, pooled though).
Indeed, having the DocumentId available right away would be great. I've since come up with a relatively simple workaround, costing a redundant join but no custom stuff needed, so works for me until a proper solution exists:
var job = await session.Query<Job, JobIndex>(x => x.Id == index.Id).FirstOrDefaultAsync();
Another problem I discovered with this, is that if you ever abort the inner transaction with CancelAsync, you set a flag which is never cleared, not even by BeginTransactionAsync, the session object is simply unusable afterwards. Which essentially means you have to create a new session object for every transaction (and since I have to use DI, it means I have to create a new DI scope for every transaction). I suppose that's probably not an unreasonable thing to need to do, I just wish it was documented or something.
Thanks for the help so far!
Another option would be for you to add this document id to the concrete index. Like any other value. In Orchard we do that to point to the document using a logical id, a unique identifier that is constant to the lifetime of the document (content item id) since the DocumentId
will vary for each new version of the same document.