1

We wanted to create IndexRequest, DeleteRequest, UpdateRequest and BulkRequest in Elasticsearch version 8 using JAVA APIs. But I don't see any java documentation in elasticsearch v8 official website. Previously in elasticsearch version 7, we used below code in order to perform operations.

IndexRequest indexRequest = Requests.indexRequest(index).id(key).source(source);


BulkRequest bulkRequest = Requests.bulkRequest();
bulkRequest.add(indexRequest);

Also following Elasticsearch Java API Client [8.1] , but no luck.

Problem arises when we try to do Requests.indexRequest(), this Request class is not available in version 8.

So, Is it possible to create similar request in ES version 8 also?

Update 1:-

My point here is that I need to keep a list of request operation which maybe arbitrary ( maybe 1st five are inserts, next 2 are update and next 2 are delete requests and at the end 1 insert operation ). And that list needed to be flushed via Bulk maintaining the type of request received. I am using BulkRequest.Builder bulkRequestBuilder = new BulkRequest.Builder();

But my issue is with bulk update. I am unable to find any update API for bulkrequest for elasticsearch version 8.

For Insert:-

bulkRequestBuilder.operations(op -> op.index(idx -> idx.index(index).id(key).document(source)));

For Delete:-

bulkRequestBuilder.operations(op -> op.delete(d -> d.index(index).id(key)));

And flushing the bulk operation:-

BulkResponse bulkResponse = client.bulk(bulkRequestBuilder.build());

I am looking for something similar to above mentioned insert and delete operation.

Like, bulkRequestBuilder.operations(op->op.update(u->u.index(index).id(key)....))

Dunggeon
  • 92
  • 1
  • 1
  • 11

2 Answers2

1

You can use the refer the following code which I used to bulk index.

String PRODUCT_INDEX="product"
final BulkResponse bulkResponse = esUtil.getESClient().bulk(builder -> {
                for (Product product : products) {
                    builder.index(PRODUCT_INDEX)
                            .operations(ob -> {
                                ob.index(ib -> ib.document(product).pipeline("score").id(product.getId())));
                                return ob;
                            });
                }
                return builder;
            });
Amit
  • 30,756
  • 6
  • 57
  • 88
1

You can use Fluent DSL like below as mentioned here:

List<Product> products = fetchProducts();

BulkRequest.Builder br = new BulkRequest.Builder();

for (Product product : products) {
    br.operations(op -> op           
        .index(idx -> idx            
            .index("products")       
            .id(product.getSku())
            .document(product)
        )
    );
}

BulkResponse result = esClient.bulk(br.build());

You can use Classic Builder like below (Not Recommndate):

IndexRequest.Builder<Product> indexReqBuilder = new IndexRequest.Builder<>();
indexReqBuilder.index("product");
indexReqBuilder.id("id");
indexReqBuilder.document(product);
        
List<BulkOperation> list = new ArrayList<BulkOperation>();
list.add(indexReqBuilder);
        
BulkRequest.Builder br = new BulkRequest.Builder();
br.index("");
br.operations(list);
        
client.bulk(br.build());

Update Request:

As mentioned here in document, UpdateRequest class support TDocument and TPartialDocument as parameter. when you want to index document as parial document (means only update) then you can use TPartialDocument and when you want to index document as upsert then you can use TDocument. you can pass Void class for other parameter.

You can check this discussion as well which give you some understanding.

client.update(b -> b
                .index("")
                .id("")
                .doc(product),
                Product.class
            );
client.update(new UpdateRequest.Builder<Void, Product>()
                .index("product")
                .id("")
                .doc(product)
                .build(),
                Void.class
            );

Bulk Update request:

BulkRequest.Builder br = new BulkRequest.Builder();
for (Product product : products) {
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(product);
    br.operations(op -> op
                    .update(idx -> idx.index("products").id("").withJson(new StringReader(json))));
        }
Sagar Patel
  • 4,993
  • 1
  • 8
  • 19
  • Thanks for reply. Your solution as well as @Amit's solution helped me a lot. Can you help me in how to create `UpdateRequest` in elasticsearch version 8. Similar to below version 7 code. `UpdateRequest updateRequest = new UpdateRequest().index(index).id(key).doc(source).docAsUpsert(isUpsert);` – Dunggeon Apr 28 '22 at 09:47
  • 1
    I have updated my answer. please check. there are no example available for `UpdateRequest` so difficult to implement. – Sagar Patel Apr 28 '22 at 10:08
  • Thanks @Sagar Patel, Although your answer regarding UpdateRequest is suitable for older elasticsearch version. But can you help me in finding solution for updaterequest in bulk for elasticsearch version 8. – Dunggeon Apr 29 '22 at 04:33
  • @PiyushKumar answer which i have posted it is for version 8 only. they dont have `upsert` method in new version. if you want to pass partial document then you need to pass `` and if document as `upsert` then you need to pass `` – Sagar Patel Apr 29 '22 at 04:37
  • Thanks for reply. Your solution helped me a lot. But my point here is that I need to keep a list of request operation which maybe arbitrary ( maybe 1st five are inserts, next 2 are update and next 2 are delete requests and at the end 1 insert operation ). And that list needed to be flushed via Bulk maintaining the type of request received. I am using `BulkRequest.Builder bulkRequestBuilder`. continue......... – Dunggeon May 04 '22 at 06:02
  • cont... For insert :- `bulkRequestBuilder.operations(op -> op.index(idx -> idx.index(index).id(key).document(source)));` For delete:- `bulkRequestBuilder.operations(op -> op.delete(d -> d.index(index).id(key)));` and at the end I am doing it, ` BulkResponse bulkResponse = client.bulk(bulkRequestBuilder.build());` But my issue is with bulk update. I am unable to find any update API for bulkrequest. Can you help me in this regard. – Dunggeon May 04 '22 at 06:03
  • am looking for something similar mentioned below, but I am not able to add update document map in bulk update operation, `bulkRequestBuilder.operations(op->op.update(u->u.index(index).id(key)))` – Dunggeon May 04 '22 at 06:05
  • @PiyushKumar as far as i know it will be same as insert and delete. something like `bulkRequestBuilder.operations(op -> op.update(d -> d.index(index).id(key),Void.class))` – Sagar Patel May 04 '22 at 06:06
  • But where should I add my updated document, void.class I understand but what about newly added field, which needed to be updated ? – Dunggeon May 04 '22 at 06:09
  • @PiyushKumar You need to pass `.doc(product)` for your document same as you are passing for index request like `bulkRequestBuilder.operations(op -> op.update(d -> d.index(index).id(key).doc(product),Void.class))` – Sagar Patel May 04 '22 at 06:31
  • Unfortunately , `.doc(product)` method is not available. – Dunggeon May 04 '22 at 06:42
  • @PiyushKumar Sorry my bad. you need to convert your object to the json and then pass . i have updated my answer please check – Sagar Patel May 04 '22 at 07:18