0
# Action Framework
1
2
Core action system for document operations, bulk processing, and the underlying request/response infrastructure. The action framework provides the foundation for all OpenSearch operations with typed requests, responses, and async execution patterns.
3
4
## Capabilities
5
6
### Base Action Framework
7
8
Core interfaces and classes that form the foundation of the OpenSearch action system.
9
10
```java { .api }
11
/**
12
* Base class defining action types with typed request and response handling
13
*/
14
abstract class ActionType<Response extends ActionResponse> implements Streamable {
15
/**
16
* Get action name identifier
17
*/
18
String name();
19
20
/**
21
* Create new response instance for deserialization
22
*/
23
Response newResponse();
24
25
/**
26
* Get response class
27
*/
28
Class<Response> getResponseClass();
29
}
30
31
/**
32
* Base class for all action requests with validation and streaming support
33
*/
34
abstract class ActionRequest implements Streamable, Validatable {
35
/**
36
* Validate request parameters and return validation errors
37
* @return Validation exception with error details, or null if valid
38
*/
39
ActionRequestValidationException validate();
40
41
/**
42
* Create request builder for this request type
43
*/
44
ActionRequestBuilder<?, ?, ?> createBuilder();
45
46
/**
47
* Get description of the request for logging and monitoring
48
*/
49
String getDescription();
50
}
51
52
/**
53
* Base class for all action responses with streaming support
54
*/
55
abstract class ActionResponse implements Streamable {
56
/**
57
* Read response from input stream
58
* @param in Input stream to read from
59
*/
60
void readFrom(StreamInput in) throws IOException;
61
62
/**
63
* Write response to output stream
64
* @param out Output stream to write to
65
*/
66
void writeTo(StreamOutput out) throws IOException;
67
}
68
69
/**
70
* Builder pattern base class for constructing action requests
71
*/
72
abstract class ActionRequestBuilder<Request extends ActionRequest, Response extends ActionResponse,
73
RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder>> {
74
75
/**
76
* Get the action type
77
*/
78
ActionType<Response> action();
79
80
/**
81
* Get the request being built
82
*/
83
Request request();
84
85
/**
86
* Execute request asynchronously
87
* @param listener Callback for response handling
88
*/
89
void execute(ActionListener<Response> listener);
90
91
/**
92
* Execute request synchronously and return response
93
*/
94
Response get();
95
96
/**
97
* Execute request with timeout
98
* @param timeout Maximum time to wait for response
99
*/
100
Response get(TimeValue timeout);
101
}
102
```
103
104
### Document Write Operations
105
106
Core document manipulation operations including indexing, updating, and deletion.
107
108
```java { .api }
109
/**
110
* Base class for all document write operations (index, update, delete)
111
*/
112
abstract class DocWriteRequest<T extends DocWriteRequest<T>> extends ActionRequest {
113
/**
114
* Get target index name
115
*/
116
String index();
117
118
/**
119
* Get document ID
120
*/
121
String id();
122
123
/**
124
* Get routing value for shard selection
125
*/
126
String routing();
127
128
/**
129
* Set routing value
130
* @param routing Routing value for shard selection
131
*/
132
T routing(String routing);
133
134
/**
135
* Get operation type (INDEX, CREATE, UPDATE, DELETE)
136
*/
137
OpType opType();
138
139
/**
140
* Set operation type
141
* @param opType Type of write operation
142
*/
143
T opType(OpType opType);
144
145
/**
146
* Get version for optimistic concurrency control
147
*/
148
long version();
149
150
/**
151
* Set document version
152
* @param version Document version for conflict detection
153
*/
154
T version(long version);
155
156
/**
157
* Get version type
158
*/
159
VersionType versionType();
160
161
/**
162
* Set version type for conflict resolution
163
* @param versionType Version type (INTERNAL, EXTERNAL, EXTERNAL_GTE)
164
*/
165
T versionType(VersionType versionType);
166
167
/**
168
* Document write operation types
169
*/
170
enum OpType {
171
INDEX, CREATE, UPDATE, DELETE
172
}
173
}
174
175
/**
176
* Base response class for document write operations
177
*/
178
abstract class DocWriteResponse extends ActionResponse {
179
/**
180
* Get target index name
181
*/
182
String getIndex();
183
184
/**
185
* Get document ID
186
*/
187
String getId();
188
189
/**
190
* Get document version after operation
191
*/
192
long getVersion();
193
194
/**
195
* Get operation result (CREATED, UPDATED, DELETED, NOT_FOUND, NOOP)
196
*/
197
Result getResult();
198
199
/**
200
* Get shard information where operation was performed
201
*/
202
ReplicationResponse.ShardInfo getShardInfo();
203
204
/**
205
* Get primary term for the document
206
*/
207
long getPrimaryTerm();
208
209
/**
210
* Get sequence number for the document
211
*/
212
long getSeqNo();
213
214
/**
215
* Document write operation results
216
*/
217
enum Result {
218
CREATED, UPDATED, DELETED, NOT_FOUND, NOOP
219
}
220
}
221
222
/**
223
* Request to index a document (create or update)
224
*/
225
class IndexRequest extends DocWriteRequest<IndexRequest> {
226
/**
227
* Create index request for specified index
228
* @param index Target index name
229
*/
230
IndexRequest(String index);
231
232
/**
233
* Set document ID
234
* @param id Document identifier
235
*/
236
IndexRequest id(String id);
237
238
/**
239
* Set document source from JSON string
240
* @param source Document content as JSON
241
* @param xContentType Content type of the source
242
*/
243
IndexRequest source(String source, XContentType xContentType);
244
245
/**
246
* Set document source from map
247
* @param source Document content as key-value pairs
248
*/
249
IndexRequest source(Map<String, Object> source);
250
251
/**
252
* Set document source from byte array
253
* @param source Document content as bytes
254
* @param xContentType Content type of the source
255
*/
256
IndexRequest source(byte[] source, XContentType xContentType);
257
258
/**
259
* Set create-only flag (fail if document exists)
260
* @param create Whether to only create (not update) documents
261
*/
262
IndexRequest create(boolean create);
263
264
/**
265
* Set request timeout
266
* @param timeout Operation timeout
267
*/
268
IndexRequest timeout(String timeout);
269
270
/**
271
* Set refresh policy for when changes become visible
272
* @param refreshPolicy When to refresh (NONE, IMMEDIATE, WAIT_UNTIL)
273
*/
274
IndexRequest setRefreshPolicy(WriteRequest.RefreshPolicy refreshPolicy);
275
276
/**
277
* Get document source
278
*/
279
BytesReference source();
280
281
/**
282
* Get content type of the source
283
*/
284
XContentType getContentType();
285
}
286
287
/**
288
* Response for index operations containing operation result and metadata
289
*/
290
class IndexResponse extends DocWriteResponse {
291
/**
292
* Get index response status
293
*/
294
RestStatus status();
295
296
/**
297
* Check if document was created (vs updated)
298
*/
299
boolean isCreated();
300
}
301
302
/**
303
* Request to retrieve a document by ID
304
*/
305
class GetRequest extends ActionRequest {
306
/**
307
* Create get request for document
308
* @param index Index name
309
* @param id Document ID
310
*/
311
GetRequest(String index, String id);
312
313
/**
314
* Set routing value for shard selection
315
* @param routing Routing value
316
*/
317
GetRequest routing(String routing);
318
319
/**
320
* Set fields to include in response
321
* @param fields Field names to retrieve
322
*/
323
GetRequest storedFields(String... fields);
324
325
/**
326
* Set source filtering
327
* @param fetchSource Whether to fetch document source
328
*/
329
GetRequest fetchSourceContext(FetchSourceContext fetchSource);
330
331
/**
332
* Set document version for conflict detection
333
* @param version Expected document version
334
*/
335
GetRequest version(long version);
336
337
/**
338
* Set version type
339
* @param versionType Version type for conflict resolution
340
*/
341
GetRequest versionType(VersionType versionType);
342
343
/**
344
* Set real-time flag
345
* @param realtime Whether to return real-time data or from index
346
*/
347
GetRequest realtime(boolean realtime);
348
349
/**
350
* Set refresh flag
351
* @param refresh Whether to refresh before get
352
*/
353
GetRequest refresh(boolean refresh);
354
355
/**
356
* Get target index
357
*/
358
String index();
359
360
/**
361
* Get document ID
362
*/
363
String id();
364
}
365
366
/**
367
* Response for get operations containing document data and metadata
368
*/
369
class GetResponse extends ActionResponse {
370
/**
371
* Get index name
372
*/
373
String getIndex();
374
375
/**
376
* Get document ID
377
*/
378
String getId();
379
380
/**
381
* Get document version
382
*/
383
long getVersion();
384
385
/**
386
* Check if document exists
387
*/
388
boolean isExists();
389
390
/**
391
* Get document source as string
392
*/
393
String getSourceAsString();
394
395
/**
396
* Get document source as map
397
*/
398
Map<String, Object> getSourceAsMap();
399
400
/**
401
* Get document source as bytes
402
*/
403
BytesReference getSourceAsBytesRef();
404
405
/**
406
* Get stored fields
407
*/
408
Map<String, DocumentField> getFields();
409
410
/**
411
* Check if source was found
412
*/
413
boolean isSourceEmpty();
414
}
415
```
416
417
### Update Operations
418
419
Document update operations with scripting and upsert support.
420
421
```java { .api }
422
/**
423
* Request to update a document with partial updates, scripts, or upserts
424
*/
425
class UpdateRequest extends DocWriteRequest<UpdateRequest> {
426
/**
427
* Create update request for document
428
* @param index Index name
429
* @param id Document ID
430
*/
431
UpdateRequest(String index, String id);
432
433
/**
434
* Set partial document for merging
435
* @param doc Partial document content
436
* @param xContentType Content type of the document
437
*/
438
UpdateRequest doc(String doc, XContentType xContentType);
439
440
/**
441
* Set partial document from map
442
* @param source Partial document as key-value pairs
443
*/
444
UpdateRequest doc(Map<String, Object> source);
445
446
/**
447
* Set upsert document (created if document doesn't exist)
448
* @param upsert Document to insert if not found
449
* @param xContentType Content type of the upsert document
450
*/
451
UpdateRequest upsert(String upsert, XContentType xContentType);
452
453
/**
454
* Set upsert document from map
455
* @param source Upsert document as key-value pairs
456
*/
457
UpdateRequest upsert(Map<String, Object> source);
458
459
/**
460
* Set script for update operation
461
* @param script Script to execute for update
462
*/
463
UpdateRequest script(Script script);
464
465
/**
466
* Set whether to return updated document source
467
* @param fetchSource Whether to fetch source in response
468
*/
469
UpdateRequest fetchSource(boolean fetchSource);
470
471
/**
472
* Set source filtering for response
473
* @param fetchSourceContext Source filtering configuration
474
*/
475
UpdateRequest fetchSource(FetchSourceContext fetchSourceContext);
476
477
/**
478
* Set scripted upsert flag
479
* @param scriptedUpsert Whether to use script for upsert
480
*/
481
UpdateRequest scriptedUpsert(boolean scriptedUpsert);
482
483
/**
484
* Set doc as upsert flag
485
* @param docAsUpsert Whether to use doc as upsert
486
*/
487
UpdateRequest docAsUpsert(boolean docAsUpsert);
488
489
/**
490
* Set detect noop flag
491
* @param detectNoop Whether to detect no-op updates
492
*/
493
UpdateRequest detectNoop(boolean detectNoop);
494
495
/**
496
* Set retry on conflict count
497
* @param retryOnConflict Number of times to retry on version conflicts
498
*/
499
UpdateRequest retryOnConflict(int retryOnConflict);
500
501
/**
502
* Get partial document
503
*/
504
IndexRequest doc();
505
506
/**
507
* Get upsert document
508
*/
509
IndexRequest upsertRequest();
510
511
/**
512
* Get update script
513
*/
514
Script script();
515
}
516
517
/**
518
* Response for update operations containing update result and optional document data
519
*/
520
class UpdateResponse extends DocWriteResponse {
521
/**
522
* Get get result containing document data
523
*/
524
GetResult getGetResult();
525
526
/**
527
* Check if get result is available
528
*/
529
boolean hasGetResult();
530
}
531
532
/**
533
* Request to delete a document by ID
534
*/
535
class DeleteRequest extends DocWriteRequest<DeleteRequest> {
536
/**
537
* Create delete request for document
538
* @param index Index name
539
* @param id Document ID
540
*/
541
DeleteRequest(String index, String id);
542
543
/**
544
* Set request timeout
545
* @param timeout Operation timeout
546
*/
547
DeleteRequest timeout(String timeout);
548
549
/**
550
* Set refresh policy
551
* @param refreshPolicy When to refresh after delete
552
*/
553
DeleteRequest setRefreshPolicy(WriteRequest.RefreshPolicy refreshPolicy);
554
}
555
556
/**
557
* Response for delete operations containing deletion result
558
*/
559
class DeleteResponse extends DocWriteResponse {
560
/**
561
* Check if document was found and deleted
562
*/
563
boolean isFound();
564
}
565
```
566
567
### Bulk Operations
568
569
Batch processing for multiple document operations with efficient execution.
570
571
```java { .api }
572
/**
573
* Request to execute multiple document operations in a single batch
574
*/
575
class BulkRequest extends ActionRequest {
576
/**
577
* Create empty bulk request
578
*/
579
BulkRequest();
580
581
/**
582
* Create bulk request with initial capacity
583
* @param globalIndex Default index for requests without explicit index
584
*/
585
BulkRequest(String globalIndex);
586
587
/**
588
* Add document write request to bulk operation
589
* @param request Document operation (index, update, delete)
590
*/
591
BulkRequest add(DocWriteRequest<?> request);
592
593
/**
594
* Add index request to bulk operation
595
* @param indexRequest Index request to add
596
*/
597
BulkRequest add(IndexRequest indexRequest);
598
599
/**
600
* Add update request to bulk operation
601
* @param updateRequest Update request to add
602
*/
603
BulkRequest add(UpdateRequest updateRequest);
604
605
/**
606
* Add delete request to bulk operation
607
* @param deleteRequest Delete request to add
608
*/
609
BulkRequest add(DeleteRequest deleteRequest);
610
611
/**
612
* Add requests from byte array (newline-delimited JSON)
613
* @param data Bulk request data in NDJSON format
614
* @param xContentType Content type of the data
615
*/
616
BulkRequest add(byte[] data, XContentType xContentType);
617
618
/**
619
* Set global refresh policy for all operations
620
* @param refreshPolicy When to refresh after operations
621
*/
622
BulkRequest setRefreshPolicy(WriteRequest.RefreshPolicy refreshPolicy);
623
624
/**
625
* Set request timeout
626
* @param timeout Operation timeout
627
*/
628
BulkRequest timeout(String timeout);
629
630
/**
631
* Get number of operations in bulk request
632
*/
633
int numberOfActions();
634
635
/**
636
* Get list of requests
637
*/
638
List<DocWriteRequest<?>> requests();
639
640
/**
641
* Get estimated size of the bulk request
642
*/
643
long estimatedSizeInBytes();
644
}
645
646
/**
647
* Response for bulk operations containing results for each individual operation
648
*/
649
class BulkResponse extends ActionResponse {
650
/**
651
* Get execution time for entire bulk operation
652
*/
653
TimeValue getTook();
654
655
/**
656
* Check if any operations had errors
657
*/
658
boolean hasFailures();
659
660
/**
661
* Get failure message summary
662
*/
663
String buildFailureMessage();
664
665
/**
666
* Get results for all operations
667
*/
668
BulkItemResponse[] getItems();
669
670
/**
671
* Get results as iterable
672
*/
673
Iterable<BulkItemResponse> items();
674
675
/**
676
* Get ingest pipeline execution time
677
*/
678
TimeValue getIngestTook();
679
}
680
681
/**
682
* Individual operation result within a bulk response
683
*/
684
class BulkItemResponse implements Streamable {
685
/**
686
* Get operation index in bulk request
687
*/
688
int getItemId();
689
690
/**
691
* Get operation type (index, create, update, delete)
692
*/
693
String getOpType();
694
695
/**
696
* Check if operation failed
697
*/
698
boolean isFailed();
699
700
/**
701
* Get operation response (if successful)
702
*/
703
<T extends DocWriteResponse> T getResponse();
704
705
/**
706
* Get failure details (if failed)
707
*/
708
BulkItemResponse.Failure getFailure();
709
710
/**
711
* Get operation version
712
*/
713
long getVersion();
714
715
/**
716
* Get target index name
717
*/
718
String getIndex();
719
720
/**
721
* Get document ID
722
*/
723
String getId();
724
725
/**
726
* Failure information for failed bulk operations
727
*/
728
static class Failure implements Streamable {
729
/**
730
* Get target index
731
*/
732
String getIndex();
733
734
/**
735
* Get document ID
736
*/
737
String getId();
738
739
/**
740
* Get failure cause
741
*/
742
Exception getCause();
743
744
/**
745
* Get error message
746
*/
747
String getMessage();
748
749
/**
750
* Get HTTP status code
751
*/
752
RestStatus getStatus();
753
}
754
}
755
756
/**
757
* Container for bulk request items with metadata
758
*/
759
class BulkItemRequest implements Streamable {
760
/**
761
* Create bulk item request
762
* @param id Item index in bulk request
763
* @param request Document write request
764
*/
765
BulkItemRequest(int id, DocWriteRequest<?> request);
766
767
/**
768
* Get item ID
769
*/
770
int id();
771
772
/**
773
* Get document write request
774
*/
775
DocWriteRequest<?> request();
776
777
/**
778
* Get abort flag
779
*/
780
boolean isAborted();
781
782
/**
783
* Set abort flag
784
* @param abort Whether to abort this operation
785
*/
786
BulkItemRequest abort(boolean abort);
787
}
788
```
789
790
### Multi-Get Operations
791
792
Batch retrieval of multiple documents by ID with efficient execution.
793
794
```java { .api }
795
/**
796
* Request to retrieve multiple documents by ID in a single batch operation
797
*/
798
class MultiGetRequest extends ActionRequest {
799
/**
800
* Create empty multi-get request
801
*/
802
MultiGetRequest();
803
804
/**
805
* Add get request to batch
806
* @param item Multi-get item specifying document to retrieve
807
*/
808
MultiGetRequest add(MultiGetRequest.Item item);
809
810
/**
811
* Add get request with index and ID
812
* @param index Index name
813
* @param id Document ID
814
*/
815
MultiGetRequest add(String index, String id);
816
817
/**
818
* Set global source filtering
819
* @param fetchSource Whether to fetch document sources
820
*/
821
MultiGetRequest fetchSourceContext(FetchSourceContext fetchSource);
822
823
/**
824
* Set real-time flag for all requests
825
* @param realtime Whether to get real-time data
826
*/
827
MultiGetRequest realtime(boolean realtime);
828
829
/**
830
* Set refresh flag for all requests
831
* @param refresh Whether to refresh before get
832
*/
833
MultiGetRequest refresh(boolean refresh);
834
835
/**
836
* Get list of items to retrieve
837
*/
838
List<MultiGetRequest.Item> getItems();
839
840
/**
841
* Individual item in multi-get request
842
*/
843
static class Item implements Streamable {
844
/**
845
* Create multi-get item
846
* @param index Index name
847
* @param id Document ID
848
*/
849
Item(String index, String id);
850
851
/**
852
* Set routing value
853
* @param routing Routing for shard selection
854
*/
855
Item routing(String routing);
856
857
/**
858
* Set stored fields to retrieve
859
* @param fields Field names to include
860
*/
861
Item storedFields(String... fields);
862
863
/**
864
* Set source filtering
865
* @param fetchSourceContext Source filtering configuration
866
*/
867
Item fetchSourceContext(FetchSourceContext fetchSourceContext);
868
869
/**
870
* Set document version
871
* @param version Expected document version
872
*/
873
Item version(long version);
874
875
/**
876
* Set version type
877
* @param versionType Version type for conflict resolution
878
*/
879
Item versionType(VersionType versionType);
880
881
/**
882
* Get index name
883
*/
884
String index();
885
886
/**
887
* Get document ID
888
*/
889
String id();
890
}
891
}
892
893
/**
894
* Response for multi-get operations containing results for each requested document
895
*/
896
class MultiGetResponse extends ActionResponse {
897
/**
898
* Get results for all requested documents
899
*/
900
MultiGetItemResponse[] getResponses();
901
902
/**
903
* Get responses as iterable
904
*/
905
Iterable<MultiGetItemResponse> responses();
906
}
907
908
/**
909
* Individual document result within a multi-get response
910
*/
911
class MultiGetItemResponse implements Streamable {
912
/**
913
* Create multi-get item response with get response
914
* @param response Get response for the item
915
* @param failure Failure information (null if successful)
916
*/
917
MultiGetItemResponse(GetResponse response, MultiGetResponse.Failure failure);
918
919
/**
920
* Get document response (if successful)
921
*/
922
GetResponse getResponse();
923
924
/**
925
* Get failure details (if failed)
926
*/
927
MultiGetResponse.Failure getFailure();
928
929
/**
930
* Check if retrieval failed
931
*/
932
boolean isFailed();
933
934
/**
935
* Get index name
936
*/
937
String getIndex();
938
939
/**
940
* Get document ID
941
*/
942
String getId();
943
}
944
```
945
946
## Usage Examples
947
948
### Basic Document Operations
949
950
```java
951
import org.opensearch.action.index.IndexRequest;
952
import org.opensearch.action.index.IndexResponse;
953
import org.opensearch.action.get.GetRequest;
954
import org.opensearch.action.get.GetResponse;
955
import org.opensearch.action.update.UpdateRequest;
956
import org.opensearch.action.delete.DeleteRequest;
957
import org.opensearch.common.xcontent.XContentType;
958
959
// Index a document
960
IndexRequest indexRequest = new IndexRequest("products");
961
indexRequest.id("1");
962
indexRequest.source("""
963
{
964
"name": "Gaming Laptop",
965
"price": 1299.99,
966
"category": "electronics",
967
"brand": "TechCorp",
968
"in_stock": true,
969
"tags": ["gaming", "laptop", "high-performance"]
970
}
971
""", XContentType.JSON);
972
973
indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
974
975
IndexResponse indexResponse = client.index(indexRequest);
976
System.out.println("Document indexed: " + indexResponse.getResult());
977
System.out.println("Version: " + indexResponse.getVersion());
978
System.out.println("Created: " + indexResponse.status() == RestStatus.CREATED);
979
980
// Retrieve the document
981
GetRequest getRequest = new GetRequest("products", "1");
982
GetResponse getResponse = client.get(getRequest);
983
984
if (getResponse.isExists()) {
985
System.out.println("Document found:");
986
System.out.println("Source: " + getResponse.getSourceAsString());
987
System.out.println("Version: " + getResponse.getVersion());
988
989
Map<String, Object> source = getResponse.getSourceAsMap();
990
System.out.println("Product name: " + source.get("name"));
991
System.out.println("Price: " + source.get("price"));
992
} else {
993
System.out.println("Document not found");
994
}
995
996
// Update the document
997
UpdateRequest updateRequest = new UpdateRequest("products", "1");
998
updateRequest.doc(Map.of(
999
"price", 1199.99,
1000
"sale", true,
1001
"updated_at", "2024-01-15T10:30:00Z"
1002
));
1003
updateRequest.fetchSource(true); // Return updated document
1004
1005
UpdateResponse updateResponse = client.update(updateRequest);
1006
System.out.println("Document updated: " + updateResponse.getResult());
1007
if (updateResponse.hasGetResult()) {
1008
System.out.println("Updated source: " + updateResponse.getGetResult().sourceAsString());
1009
}
1010
1011
// Delete the document
1012
DeleteRequest deleteRequest = new DeleteRequest("products", "1");
1013
DeleteResponse deleteResponse = client.delete(deleteRequest);
1014
System.out.println("Document deleted: " + deleteResponse.getResult());
1015
System.out.println("Found: " + deleteResponse.isFound());
1016
```
1017
1018
### Bulk Operations
1019
1020
```java
1021
import org.opensearch.action.bulk.BulkRequest;
1022
import org.opensearch.action.bulk.BulkResponse;
1023
import org.opensearch.action.bulk.BulkItemResponse;
1024
1025
// Create bulk request
1026
BulkRequest bulkRequest = new BulkRequest();
1027
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
1028
1029
// Add multiple index operations
1030
for (int i = 1; i <= 100; i++) {
1031
IndexRequest indexRequest = new IndexRequest("products");
1032
indexRequest.id(String.valueOf(i));
1033
indexRequest.source(Map.of(
1034
"name", "Product " + i,
1035
"price", Math.random() * 1000 + 10,
1036
"category", i % 2 == 0 ? "electronics" : "books",
1037
"created_at", "2024-01-" + String.format("%02d", (i % 28) + 1)
1038
));
1039
1040
bulkRequest.add(indexRequest);
1041
}
1042
1043
// Add some update operations
1044
UpdateRequest updateRequest = new UpdateRequest("products", "50");
1045
updateRequest.doc(Map.of("featured", true, "priority", "high"));
1046
bulkRequest.add(updateRequest);
1047
1048
// Add a delete operation
1049
DeleteRequest deleteRequest = new DeleteRequest("products", "99");
1050
bulkRequest.add(deleteRequest);
1051
1052
// Execute bulk request
1053
BulkResponse bulkResponse = client.bulk(bulkRequest);
1054
1055
System.out.println("Bulk operation took: " + bulkResponse.getTook());
1056
System.out.println("Has failures: " + bulkResponse.hasFailures());
1057
1058
if (bulkResponse.hasFailures()) {
1059
System.out.println("Failure message: " + bulkResponse.buildFailureMessage());
1060
}
1061
1062
// Process individual results
1063
int successCount = 0;
1064
int failureCount = 0;
1065
1066
for (BulkItemResponse bulkItemResponse : bulkResponse) {
1067
if (bulkItemResponse.isFailed()) {
1068
failureCount++;
1069
BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
1070
System.err.println("Failed operation for doc " + failure.getId() + ": " + failure.getMessage());
1071
} else {
1072
successCount++;
1073
DocWriteResponse response = bulkItemResponse.getResponse();
1074
System.out.println("Success: " + response.getResult() + " for doc " + response.getId());
1075
}
1076
}
1077
1078
System.out.println("Successful operations: " + successCount);
1079
System.out.println("Failed operations: " + failureCount);
1080
```
1081
1082
### Multi-Get Operations
1083
1084
```java
1085
import org.opensearch.action.get.MultiGetRequest;
1086
import org.opensearch.action.get.MultiGetResponse;
1087
import org.opensearch.action.get.MultiGetItemResponse;
1088
import org.opensearch.search.fetch.subphase.FetchSourceContext;
1089
1090
// Create multi-get request
1091
MultiGetRequest multiGetRequest = new MultiGetRequest();
1092
1093
// Add documents to retrieve
1094
multiGetRequest.add("products", "1");
1095
multiGetRequest.add("products", "2");
1096
multiGetRequest.add("products", "3");
1097
1098
// Add item with specific field filtering
1099
MultiGetRequest.Item item = new MultiGetRequest.Item("products", "4");
1100
item.fetchSourceContext(new FetchSourceContext(true, new String[]{"name", "price"}, null));
1101
multiGetRequest.add(item);
1102
1103
// Add item from different index
1104
multiGetRequest.add("orders", "order_123");
1105
1106
// Execute multi-get
1107
MultiGetResponse multiGetResponse = client.multiGet(multiGetRequest);
1108
1109
// Process results
1110
for (MultiGetItemResponse itemResponse : multiGetResponse) {
1111
if (!itemResponse.isFailed()) {
1112
GetResponse response = itemResponse.getResponse();
1113
if (response.isExists()) {
1114
System.out.println("Document " + response.getId() + " from " + response.getIndex());
1115
System.out.println("Source: " + response.getSourceAsString());
1116
} else {
1117
System.out.println("Document " + response.getId() + " not found");
1118
}
1119
} else {
1120
System.err.println("Failed to retrieve document: " + itemResponse.getFailure().getMessage());
1121
}
1122
}
1123
```
1124
1125
### Advanced Update with Scripts
1126
1127
```java
1128
import org.opensearch.script.Script;
1129
import org.opensearch.script.ScriptType;
1130
1131
// Update with inline script
1132
UpdateRequest scriptUpdateRequest = new UpdateRequest("products", "1");
1133
1134
Script incrementScript = new Script(
1135
ScriptType.INLINE,
1136
"painless",
1137
"ctx._source.view_count = (ctx._source.view_count ?: 0) + params.increment",
1138
Map.of("increment", 1)
1139
);
1140
1141
scriptUpdateRequest.script(incrementScript);
1142
scriptUpdateRequest.upsert(Map.of("view_count", 1)); // Create with initial value if doesn't exist
1143
1144
UpdateResponse scriptUpdateResponse = client.update(scriptUpdateRequest);
1145
System.out.println("Script update result: " + scriptUpdateResponse.getResult());
1146
1147
// Update with conditional logic
1148
UpdateRequest conditionalUpdate = new UpdateRequest("products", "2");
1149
1150
Script conditionalScript = new Script(
1151
ScriptType.INLINE,
1152
"painless",
1153
"""
1154
if (ctx._source.price > params.threshold) {
1155
ctx._source.discount = params.discount_rate;
1156
ctx._source.sale_price = ctx._source.price * (1 - params.discount_rate);
1157
} else {
1158
ctx.op = 'noop';
1159
}
1160
""",
1161
Map.of(
1162
"threshold", 100.0,
1163
"discount_rate", 0.15
1164
)
1165
);
1166
1167
conditionalUpdate.script(conditionalScript);
1168
conditionalUpdate.detectNoop(true);
1169
1170
UpdateResponse conditionalResponse = client.update(conditionalUpdate);
1171
System.out.println("Conditional update result: " + conditionalResponse.getResult());
1172
```
1173
1174
## Types
1175
1176
```java { .api }
1177
/**
1178
* Write request configuration for controlling when changes become visible
1179
*/
1180
interface WriteRequest<T extends WriteRequest<T>> {
1181
/**
1182
* Set refresh policy for the operation
1183
* @param refreshPolicy When to refresh the index
1184
*/
1185
T setRefreshPolicy(RefreshPolicy refreshPolicy);
1186
1187
/**
1188
* Get current refresh policy
1189
*/
1190
RefreshPolicy getRefreshPolicy();
1191
1192
/**
1193
* Refresh policy options
1194
*/
1195
enum RefreshPolicy {
1196
/**
1197
* No refresh (changes may not be immediately searchable)
1198
*/
1199
NONE,
1200
1201
/**
1202
* Immediate refresh (changes immediately searchable, but impacts performance)
1203
*/
1204
IMMEDIATE,
1205
1206
/**
1207
* Wait until refresh (wait for next scheduled refresh)
1208
*/
1209
WAIT_UNTIL
1210
}
1211
}
1212
1213
/**
1214
* Version types for optimistic concurrency control
1215
*/
1216
enum VersionType {
1217
/**
1218
* Internal versioning (managed by OpenSearch)
1219
*/
1220
INTERNAL,
1221
1222
/**
1223
* External versioning (managed by client application)
1224
*/
1225
EXTERNAL,
1226
1227
/**
1228
* External versioning with greater-than-or-equal semantics
1229
*/
1230
EXTERNAL_GTE
1231
}
1232
1233
/**
1234
* Source filtering configuration for controlling which fields to return
1235
*/
1236
class FetchSourceContext implements Streamable {
1237
/**
1238
* Fetch all source fields
1239
*/
1240
static final FetchSourceContext FETCH_SOURCE = new FetchSourceContext(true);
1241
1242
/**
1243
* Don't fetch any source fields
1244
*/
1245
static final FetchSourceContext DO_NOT_FETCH_SOURCE = new FetchSourceContext(false);
1246
1247
/**
1248
* Create fetch source context with include/exclude patterns
1249
* @param fetchSource Whether to fetch source
1250
* @param includes Field patterns to include
1251
* @param excludes Field patterns to exclude
1252
*/
1253
FetchSourceContext(boolean fetchSource, String[] includes, String[] excludes);
1254
1255
/**
1256
* Check if source should be fetched
1257
*/
1258
boolean fetchSource();
1259
1260
/**
1261
* Get include patterns
1262
*/
1263
String[] includes();
1264
1265
/**
1266
* Get exclude patterns
1267
*/
1268
String[] excludes();
1269
}
1270
1271
/**
1272
* Validation exception for action request parameter errors
1273
*/
1274
class ActionRequestValidationException extends OpenSearchException {
1275
/**
1276
* Add validation error
1277
* @param error Error message to add
1278
*/
1279
ActionRequestValidationException addValidationError(String error);
1280
1281
/**
1282
* Get all validation errors
1283
*/
1284
List<String> validationErrors();
1285
}
1286
1287
/**
1288
* Script configuration for update operations
1289
*/
1290
class Script implements Streamable {
1291
/**
1292
* Create inline script
1293
* @param type Script type (INLINE, STORED, FILE)
1294
* @param lang Script language (painless, expression, etc.)
1295
* @param idOrCode Script ID (for stored) or code (for inline)
1296
* @param params Script parameters
1297
*/
1298
Script(ScriptType type, String lang, String idOrCode, Map<String, Object> params);
1299
1300
/**
1301
* Get script type
1302
*/
1303
ScriptType getType();
1304
1305
/**
1306
* Get script language
1307
*/
1308
String getLang();
1309
1310
/**
1311
* Get script ID or code
1312
*/
1313
String getIdOrCode();
1314
1315
/**
1316
* Get script parameters
1317
*/
1318
Map<String, Object> getParams();
1319
}
1320
```