Skip to content

Commit 9439dbc

Browse files
committed
Add doc's sequence number + primary term to GetResult and use it for updates (#36680)
This commit adds the last sequence number and primary term of the last operation that have modified a document to `GetResult` and uses it to power the Update API. Relates #36148 Relates #10708
1 parent 7a6a79d commit 9439dbc

File tree

30 files changed

+259
-118
lines changed

30 files changed

+259
-118
lines changed

docs/plugins/ingest-attachment.asciidoc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ Returns this:
6363
"_type": "_doc",
6464
"_id": "my_id",
6565
"_version": 1,
66+
"_seq_no": 22,
67+
"_primary_term": 1,
6668
"_source": {
6769
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
6870
"attachment": {
@@ -74,7 +76,7 @@ Returns this:
7476
}
7577
}
7678
--------------------------------------------------
77-
// TESTRESPONSE
79+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
7880

7981

8082
To specify only some fields to be extracted:
@@ -146,6 +148,8 @@ Returns this:
146148
"_type": "_doc",
147149
"_id": "my_id",
148150
"_version": 1,
151+
"_seq_no": 35,
152+
"_primary_term": 1,
149153
"_source": {
150154
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
151155
"attachment": {
@@ -157,7 +161,7 @@ Returns this:
157161
}
158162
}
159163
--------------------------------------------------
160-
// TESTRESPONSE
164+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
161165

162166

163167
[source,js]
@@ -194,6 +198,8 @@ Returns this:
194198
"_type": "_doc",
195199
"_id": "my_id_2",
196200
"_version": 1,
201+
"_seq_no": 40,
202+
"_primary_term": 1,
197203
"_source": {
198204
"data": "e1xydGYxXGFuc2kNCkxvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0DQpccGFyIH0=",
199205
"max_size": 5,
@@ -206,7 +212,7 @@ Returns this:
206212
}
207213
}
208214
--------------------------------------------------
209-
// TESTRESPONSE
215+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
210216

211217

212218
[[ingest-attachment-with-arrays]]
@@ -285,6 +291,8 @@ Returns this:
285291
"_type" : "_doc",
286292
"_id" : "my_id",
287293
"_version" : 1,
294+
"_seq_no" : 50,
295+
"_primary_term" : 1,
288296
"found" : true,
289297
"_source" : {
290298
"attachments" : [
@@ -312,7 +320,7 @@ Returns this:
312320
}
313321
}
314322
--------------------------------------------------
315-
// TESTRESPONSE
323+
// TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
316324

317325

318326
Note that the `target_field` needs to be set, otherwise the

docs/plugins/ingest-geoip.asciidoc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ Which returns:
7575
"_type": "_doc",
7676
"_id": "my_id",
7777
"_version": 1,
78+
"_seq_no": 55,
79+
"_primary_term": 1,
7880
"_source": {
7981
"ip": "8.8.8.8",
8082
"geoip": {
@@ -85,7 +87,7 @@ Which returns:
8587
}
8688
}
8789
--------------------------------------------------
88-
// TESTRESPONSE
90+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term":1/"_primary_term" : $body._primary_term/]
8991

9092
Here is an example that uses the default country database and adds the
9193
geographical information to the `geo` field based on the `ip` field`. Note that
@@ -124,6 +126,8 @@ returns this:
124126
"_type": "_doc",
125127
"_id": "my_id",
126128
"_version": 1,
129+
"_seq_no": 65,
130+
"_primary_term": 1,
127131
"_source": {
128132
"ip": "8.8.8.8",
129133
"geo": {
@@ -133,7 +137,7 @@ returns this:
133137
}
134138
}
135139
--------------------------------------------------
136-
// TESTRESPONSE
140+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
137141

138142

139143
Not all IP addresses find geo information from the database, When this
@@ -174,13 +178,15 @@ Which returns:
174178
"_type" : "_doc",
175179
"_id" : "my_id",
176180
"_version" : 1,
181+
"_seq_no" : 71,
182+
"_primary_term": 1,
177183
"found" : true,
178184
"_source" : {
179185
"ip" : "80.231.5.0"
180186
}
181187
}
182188
--------------------------------------------------
183-
// TESTRESPONSE
189+
// TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
184190

185191
[[ingest-geoip-mappings-note]]
186192
===== Recognizing Location as a Geopoint

docs/plugins/ingest-user-agent.asciidoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ Which returns
5757
"_type": "_doc",
5858
"_id": "my_id",
5959
"_version": 1,
60+
"_seq_no": 22,
61+
"_primary_term": 1,
6062
"_source": {
6163
"agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
6264
"user_agent": {
@@ -73,7 +75,7 @@ Which returns
7375
}
7476
}
7577
--------------------------------------------------
76-
// TESTRESPONSE
78+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term": 1/"_primary_term" : $body._primary_term/]
7779

7880
===== Using a custom regex file
7981
To use a custom regex file for parsing the user agents, that file has to be put into the `config/ingest-user-agent` directory and

docs/reference/docs/get.asciidoc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ The result of the above get operation is:
2121
"_type" : "_doc",
2222
"_id" : "0",
2323
"_version" : 1,
24+
"_seq_no" : 10,
25+
"_primary_term" : 1,
2426
"found": true,
2527
"_source" : {
2628
"user" : "kimchy",
@@ -30,7 +32,7 @@ The result of the above get operation is:
3032
}
3133
}
3234
--------------------------------------------------
33-
// TESTRESPONSE
35+
// TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
3436

3537
The above result includes the `_index`, `_type`, `_id` and `_version`
3638
of the document we wish to retrieve, including the actual `_source`
@@ -156,6 +158,8 @@ The result of the above get operation is:
156158
"_type": "_doc",
157159
"_id": "1",
158160
"_version": 1,
161+
"_seq_no" : 22,
162+
"_primary_term" : 1,
159163
"found": true,
160164
"fields": {
161165
"tags": [
@@ -164,7 +168,7 @@ The result of the above get operation is:
164168
}
165169
}
166170
--------------------------------------------------
167-
// TESTRESPONSE
171+
// TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
168172

169173

170174
Field values fetched from the document itself are always returned as an array.
@@ -199,6 +203,8 @@ The result of the above get operation is:
199203
"_type": "_doc",
200204
"_id": "2",
201205
"_version": 1,
206+
"_seq_no" : 13,
207+
"_primary_term" : 1,
202208
"_routing": "user1",
203209
"found": true,
204210
"fields": {
@@ -208,7 +214,7 @@ The result of the above get operation is:
208214
}
209215
}
210216
--------------------------------------------------
211-
// TESTRESPONSE
217+
// TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
212218

213219
Also only leaf fields can be returned via the `stored_field` option. So object fields can't be returned and such requests
214220
will fail.

docs/reference/docs/reindex.asciidoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,13 +870,15 @@ which will return:
870870
"_index": "test2",
871871
"_type": "_doc",
872872
"_version": 1,
873+
"_seq_no": 44,
874+
"_primary_term": 1,
873875
"_source": {
874876
"text": "words words",
875877
"tag": "foo"
876878
}
877879
}
878880
--------------------------------------------------
879-
// TESTRESPONSE
881+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term": 1/"_primary_term" : $body._primary_term/]
880882

881883
[float]
882884
[[docs-reindex-slice]]

docs/reference/getting-started.asciidoc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ And the response:
426426
"_primary_term" : 1
427427
}
428428
--------------------------------------------------
429-
// TESTRESPONSE[s/"_seq_no" : 0/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
429+
// TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
430430

431431
From the above, we can see that a new customer document was successfully created inside the customer index. The document also has an internal id of 1 which we specified at index time.
432432

@@ -450,11 +450,13 @@ And the response:
450450
"_type" : "_doc",
451451
"_id" : "1",
452452
"_version" : 1,
453+
"_seq_no" : 25,
454+
"_primary_term" : 1,
453455
"found" : true,
454456
"_source" : { "name": "John Doe" }
455457
}
456458
--------------------------------------------------
457-
// TESTRESPONSE
459+
// TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
458460

459461
Nothing out of the ordinary here other than a field, `found`, stating that we found a document with the requested ID 1 and another field, `_source`, which returns the full JSON document that we indexed from the previous step.
460462

docs/reference/ingest/ingest-node.asciidoc

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -730,13 +730,15 @@ GET test/_doc/2
730730
"_type": "_doc",
731731
"_id": "2",
732732
"_version": 1,
733+
"_seq_no": 22,
734+
"_primary_term": 1,
733735
"found": true,
734736
"_source": {
735737
"foo": "bar"
736738
}
737739
}
738740
--------------------------------------------------
739-
// TESTRESPONSE
741+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term": 1/"_primary_term" : $body._primary_term/]
740742
////
741743

742744
The source document can also use dot delimited fields to represent nested fields.
@@ -967,6 +969,8 @@ GET test/_doc/2
967969
"_type": "_doc",
968970
"_id": "2",
969971
"_version": 1,
972+
"_seq_no": 34,
973+
"_primary_term": 1,
970974
"found": true,
971975
"_source": {
972976
"tags": [
@@ -976,7 +980,7 @@ GET test/_doc/2
976980
}
977981
}
978982
--------------------------------------------------
979-
// TESTRESPONSE
983+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
980984
////
981985

982986

@@ -1088,6 +1092,8 @@ GET test/_doc/1
10881092
"_type": "_doc",
10891093
"_id": "1",
10901094
"_version": 1,
1095+
"_seq_no": 60,
1096+
"_primary_term": 1,
10911097
"found": true,
10921098
"_source": {
10931099
"href": {
@@ -1097,7 +1103,7 @@ GET test/_doc/1
10971103
}
10981104
}
10991105
--------------------------------------------------
1100-
// TESTRESPONSE
1106+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
11011107

11021108

11031109
Regular expressions can be expensive and should be avoided if viable
@@ -1548,11 +1554,11 @@ PUT /myindex/_doc/1?pipeline=monthlyindex
15481554
"successful" : 1,
15491555
"failed" : 0
15501556
},
1551-
"_seq_no" : 0,
1557+
"_seq_no" : 55,
15521558
"_primary_term" : 1
15531559
}
15541560
--------------------------------------------------
1555-
// TESTRESPONSE
1561+
// TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
15561562

15571563

15581564
The above request will not index this document into the `myindex` index, but into the `myindex-2016-04-01` index because
@@ -2787,11 +2793,11 @@ Response from the index request:
27872793
"successful": 1,
27882794
"failed": 0
27892795
},
2790-
"_seq_no": 0,
2796+
"_seq_no": 66,
27912797
"_primary_term": 1,
27922798
}
27932799
--------------------------------------------------
2794-
// TESTRESPONSE
2800+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
27952801

27962802
Indexed document:
27972803

@@ -2963,11 +2969,11 @@ The response from the above index request:
29632969
"successful": 1,
29642970
"failed": 0
29652971
},
2966-
"_seq_no": 0,
2972+
"_seq_no": 89,
29672973
"_primary_term": 1,
29682974
}
29692975
--------------------------------------------------
2970-
// TESTRESPONSE
2976+
// TESTRESPONSE[s/"_seq_no": \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
29712977

29722978
In the above response, you can see that our document was actually indexed into `my_index` instead of
29732979
`any_index`. This type of manipulation is often convenient in pipelines that have various branches of transformation,

modules/percolator/src/test/java/org/elasticsearch/percolator/PercolateQueryBuilderTests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import java.util.Map;
6666
import java.util.Set;
6767

68+
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
6869
import static org.hamcrest.Matchers.equalTo;
6970
import static org.hamcrest.Matchers.sameInstance;
7071

@@ -175,12 +176,13 @@ protected GetResponse executeGet(GetRequest getRequest) {
175176
assertThat(getRequest.version(), Matchers.equalTo(indexedDocumentVersion));
176177
if (indexedDocumentExists) {
177178
return new GetResponse(
178-
new GetResult(indexedDocumentIndex, indexedDocumentType, indexedDocumentId, 0L, true,
179+
new GetResult(indexedDocumentIndex, indexedDocumentType, indexedDocumentId, 0, 1, 0L, true,
179180
documentSource.iterator().next(), Collections.emptyMap())
180181
);
181182
} else {
182183
return new GetResponse(
183-
new GetResult(indexedDocumentIndex, indexedDocumentType, indexedDocumentId, -1, false, null, Collections.emptyMap())
184+
new GetResult(indexedDocumentIndex, indexedDocumentType, indexedDocumentId, UNASSIGNED_SEQ_NO, 0, -1,
185+
false, null, Collections.emptyMap())
184186
);
185187
}
186188
}

server/src/main/java/org/elasticsearch/action/bulk/TransportShardBulkAction.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ static BulkItemResponse processUpdateResponse(final UpdateRequest updateRequest,
305305
final Tuple<XContentType, Map<String, Object>> sourceAndContent =
306306
XContentHelper.convertToMap(indexSourceAsBytes, true, updateIndexRequest.getContentType());
307307
updateResponse.setGetResult(UpdateHelper.extractGetResult(updateRequest, concreteIndex,
308+
indexResponse.getSeqNo(), indexResponse.getPrimaryTerm(),
308309
indexResponse.getVersion(), sourceAndContent.v2(), sourceAndContent.v1(), indexSourceAsBytes));
309310
}
310311
} else if (translatedResult == DocWriteResponse.Result.DELETED) {
@@ -313,7 +314,8 @@ static BulkItemResponse processUpdateResponse(final UpdateRequest updateRequest,
313314
deleteResponse.getType(), deleteResponse.getId(), deleteResponse.getSeqNo(), deleteResponse.getPrimaryTerm(),
314315
deleteResponse.getVersion(), deleteResponse.getResult());
315316

316-
final GetResult getResult = UpdateHelper.extractGetResult(updateRequest, concreteIndex, deleteResponse.getVersion(),
317+
final GetResult getResult = UpdateHelper.extractGetResult(updateRequest, concreteIndex,
318+
deleteResponse.getSeqNo(), deleteResponse.getPrimaryTerm(), deleteResponse.getVersion(),
317319
translate.updatedSourceAsMap(), translate.updateSourceContentType(), null);
318320

319321
updateResponse.setGetResult(getResult);

server/src/main/java/org/elasticsearch/action/get/GetResponse.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,20 @@ public long getVersion() {
9090
return getResult.getVersion();
9191
}
9292

93+
/**
94+
* The sequence number assigned to the last operation to have changed this document, if found.
95+
*/
96+
public long getSeqNo() {
97+
return getResult.getSeqNo();
98+
}
99+
100+
/**
101+
* The primary term of the last primary that has changed this document, if found.
102+
*/
103+
public long getPrimaryTerm() {
104+
return getResult.getPrimaryTerm();
105+
}
106+
93107
/**
94108
* The source of the document if exists.
95109
*/

0 commit comments

Comments
 (0)