Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elasticsearch Java API: Wait until document findable in search results?

I have written a REST API (javax.ws.rs) that uses the high-level Elasticsearch API. This is with ES 7.2.

The client needs to index a record, then execute a search that includes that record and there is some delay after the index operation before the document will actually appear in searches.

Is there any way to block the index operation until the newly index record appears in search results?

Failing that, is there any way to get an asynchronous notification that the document is now searchable?

To give an idea of my use case, here is the code from the client side:

  const cr = await this.client.dNodeCreate(fixedNode).toPromise();
  const fr = await this.client.dNodeGetById(cr._id).toPromise();
  await this.client.dNodeCreate(replyRoot).toPromise();

The first line causes a Index request to ES, and returns the status object. That object includes the ID of the new document.

The second line fetches the record by ID. This always works.

The third line fails. The document it attempts to index is dependent on the first document, which the REST middleware attempts to look up by a search (not by the ID). This is the equivalent of an SQL relation enforced by the REST layer.

I can always make the code work by introducing a delay (say 1500ms) before the third call but this is really a non-robust solution. It might always work in development mode (all the servers are on my laptop and no other users) but there is no way to predict how long the delay needs to be in actual production.

UPDATE: Solved.

The marked answer below seems to do the trick. For reference, the needed call in the Java API looks like this:

        IndexRequest req = new IndexRequest(DNode.INDEX);
        req.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
like image 265
AlanObject Avatar asked Sep 21 '25 01:09

AlanObject


1 Answers

The 'refresh' parameter is what you are looking for. From the Elasticsearch documentation:

Refresh (Index API): ) If true, Elasticsearch refreshes the affected shards to make this operation visible to search, if wait_for then wait for a refresh to make this operation visible to search, if false do nothing with refreshes. Valid values: true, false, wait_for. Default: false

So your index request should look something like this:

PUT /<index>/_doc/<_id>?refresh=wait_for

I do not believe there is a built-in way to get an asynchronous notification that the document is now searchable. That being said, if you already have access to the document ID it might make more sense to use that in the code instead of a search.

like image 85
Dennis Avatar answered Sep 23 '25 05:09

Dennis