Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get document (in separate transaction) after QueryIndex #538

Open
ovekaaven opened this issue Apr 6, 2024 · 3 comments
Open

How to get document (in separate transaction) after QueryIndex #538

ovekaaven opened this issue Apr 6, 2024 · 3 comments

Comments

@ovekaaven
Copy link

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.

@sebastienros
Copy link
Owner

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).

@ovekaaven
Copy link
Author

ovekaaven commented May 3, 2024

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!

@sebastienros
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants