Skip to content

Commit 86b8e28

Browse files
committed
Merge remote-tracking branch 'upstream/main' into http-aggregator-removal
2 parents 737fb67 + f48a3c3 commit 86b8e28

File tree

44 files changed

+2010
-307
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2010
-307
lines changed

benchmarks/src/main/java/org/elasticsearch/benchmark/vector/OSQScorerBenchmark.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ public void scoreFromArray(Blackhole bh) throws IOException {
126126
in.readFloats(corrections, 0, corrections.length);
127127
int addition = Short.toUnsignedInt(in.readShort());
128128
float score = scorer.score(
129-
result,
129+
result.lowerInterval(),
130+
result.upperInterval(),
131+
result.quantizedComponentSum(),
132+
result.additionalCorrection(),
130133
VectorSimilarityFunction.EUCLIDEAN,
131134
centroidDp,
132135
corrections[0],
@@ -150,7 +153,10 @@ public void scoreFromMemorySegmentOnlyVector(Blackhole bh) throws IOException {
150153
in.readFloats(corrections, 0, corrections.length);
151154
int addition = Short.toUnsignedInt(in.readShort());
152155
float score = scorer.score(
153-
result,
156+
result.lowerInterval(),
157+
result.upperInterval(),
158+
result.quantizedComponentSum(),
159+
result.additionalCorrection(),
154160
VectorSimilarityFunction.EUCLIDEAN,
155161
centroidDp,
156162
corrections[0],
@@ -175,7 +181,10 @@ public void scoreFromMemorySegmentOnlyVectorBulk(Blackhole bh) throws IOExceptio
175181
in.readFloats(corrections, 0, corrections.length);
176182
int addition = Short.toUnsignedInt(in.readShort());
177183
float score = scorer.score(
178-
result,
184+
result.lowerInterval(),
185+
result.upperInterval(),
186+
result.quantizedComponentSum(),
187+
result.additionalCorrection(),
179188
VectorSimilarityFunction.EUCLIDEAN,
180189
centroidDp,
181190
corrections[0],
@@ -196,7 +205,16 @@ public void scoreFromMemorySegmentAllBulk(Blackhole bh) throws IOException {
196205
for (int j = 0; j < numQueries; j++) {
197206
in.seek(0);
198207
for (int i = 0; i < numVectors; i += 16) {
199-
scorer.scoreBulk(binaryQueries[j], result, VectorSimilarityFunction.EUCLIDEAN, centroidDp, scratchScores);
208+
scorer.scoreBulk(
209+
binaryQueries[j],
210+
result.lowerInterval(),
211+
result.upperInterval(),
212+
result.quantizedComponentSum(),
213+
result.additionalCorrection(),
214+
VectorSimilarityFunction.EUCLIDEAN,
215+
centroidDp,
216+
scratchScores
217+
);
200218
bh.consume(scratchScores);
201219
}
202220
}

docs/changelog/119967.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 119967
2+
summary: Add `index_options` to `semantic_text` field mappings
3+
area: Mapping
4+
type: enhancement
5+
issues: [ ]

docs/changelog/129507.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 129507
2+
summary: Using a temp `IndexService` for template validation
3+
area: Indices APIs
4+
type: bug
5+
issues:
6+
- 129473

docs/changelog/129509.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 129509
2+
summary: Fix NPE in `SemanticTextHighlighter`
3+
area: Search
4+
type: bug
5+
issues:
6+
- 129501

docs/changelog/129548.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 129548
2+
summary: Fix NPE in `flat_bbq` scorer when all vectors are missing
3+
area: Vector Search
4+
type: bug
5+
issues: []

docs/reference/elasticsearch/mapping-reference/semantic-text.md

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ service.
2828

2929
Using `semantic_text`, you won’t need to specify how to generate embeddings for
3030
your data, or how to index it. The {{infer}} endpoint automatically determines
31-
the embedding generation, indexing, and query to use.
31+
the embedding generation, indexing, and query to use.
3232
Newly created indices with `semantic_text` fields using dense embeddings will be
3333
[quantized](/reference/elasticsearch/mapping-reference/dense-vector.md#dense-vector-quantization)
3434
to `bbq_hnsw` automatically.
@@ -111,6 +111,33 @@ the [Create {{infer}} API](https://www.elastic.co/docs/api/doc/elasticsearch/ope
111111
to create the endpoint. If not specified, the {{infer}} endpoint defined by
112112
`inference_id` will be used at both index and query time.
113113

114+
`index_options`
115+
: (Optional, string) Specifies the index options to override default values
116+
for the field. Currently, `dense_vector` index options are supported.
117+
For text embeddings, `index_options` may match any allowed
118+
[dense_vector index options](/reference/elasticsearch/mapping-reference/dense-vector.md#dense-vector-index-options).
119+
120+
An example of how to set index_options for a `semantic_text` field:
121+
122+
```console
123+
PUT my-index-000004
124+
{
125+
"mappings": {
126+
"properties": {
127+
"inference_field": {
128+
"type": "semantic_text",
129+
"inference_id": "my-text-embedding-endpoint",
130+
"index_options": {
131+
"dense_vector": {
132+
"type": "int4_flat"
133+
}
134+
}
135+
}
136+
}
137+
}
138+
}
139+
```
140+
114141
`chunking_settings`
115142
: (Optional, object) Settings for chunking text into smaller passages.
116143
If specified, these will override the chunking settings set in the {{infer-cap}}
@@ -138,8 +165,10 @@ To completely disable chunking, use the `none` chunking strategy.
138165
or `1`. Required for `sentence` type chunking settings
139166

140167
::::{warning}
141-
If the input exceeds the maximum token limit of the underlying model, some services (such as OpenAI) may return an
142-
error. In contrast, the `elastic` and `elasticsearch` services will automatically truncate the input to fit within the
168+
If the input exceeds the maximum token limit of the underlying model, some
169+
services (such as OpenAI) may return an
170+
error. In contrast, the `elastic` and `elasticsearch` services will
171+
automatically truncate the input to fit within the
143172
model's limit.
144173
::::
145174

@@ -173,7 +202,8 @@ For more details on chunking and how to configure chunking settings,
173202
see [Configuring chunking](https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-inference)
174203
in the Inference API documentation.
175204

176-
You can pre-chunk the input by sending it to Elasticsearch as an array of strings.
205+
You can pre-chunk the input by sending it to Elasticsearch as an array of
206+
strings.
177207
Example:
178208

179209
```console
@@ -203,15 +233,20 @@ PUT test-index/_doc/1
203233
```
204234

205235
1. The text is pre-chunked and provided as an array of strings.
206-
Each element in the array represents a single chunk that will be sent directly to the inference service without further chunking.
236+
Each element in the array represents a single chunk that will be sent
237+
directly to the inference service without further chunking.
207238

208239
**Important considerations**:
209240

210-
* When providing pre-chunked input, ensure that you set the chunking strategy to `none` to avoid additional processing.
211-
* Each chunk should be sized carefully, staying within the token limit of the inference service and the underlying model.
212-
* If a chunk exceeds the model's token limit, the behavior depends on the service:
213-
* Some services (such as OpenAI) will return an error.
214-
* Others (such as `elastic` and `elasticsearch`) will automatically truncate the input.
241+
* When providing pre-chunked input, ensure that you set the chunking strategy to
242+
`none` to avoid additional processing.
243+
* Each chunk should be sized carefully, staying within the token limit of the
244+
inference service and the underlying model.
245+
* If a chunk exceeds the model's token limit, the behavior depends on the
246+
service:
247+
* Some services (such as OpenAI) will return an error.
248+
* Others (such as `elastic` and `elasticsearch`) will automatically truncate
249+
the input.
215250

216251
Refer
217252
to [this tutorial](docs-content://solutions/search/semantic-search/semantic-search-semantic-text.md)

docs/reference/elasticsearch/rest-apis/retrieve-selected-fields.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ By default, each hit in the search response includes the document [`_source`](/r
1717
You can use both of these methods, though the `fields` option is preferred because it consults both the document data and index mappings. In some instances, you might want to use [other methods](#field-retrieval-methods) of retrieving data.
1818

1919

20-
### The `fields` option [search-fields-param]
20+
## The `fields` option [search-fields-param]
2121

2222
To retrieve specific fields in the search response, use the `fields` parameter. Because it consults the index mappings, the `fields` parameter provides several advantages over referencing the `_source` directly. Specifically, the `fields` parameter:
2323

@@ -33,7 +33,7 @@ Other mapping options are also respected, including [`ignore_above`](/reference/
3333
The `fields` option returns values in the way that matches how {{es}} indexes them. For standard fields, this means that the `fields` option looks in `_source` to find the values, then parses and formats them using the mappings. Selected fields that can’t be found in `_source` are skipped.
3434

3535

36-
#### Retrieve specific fields [search-fields-request]
36+
### Retrieve specific fields [search-fields-request]
3737

3838
The following search request uses the `fields` parameter to retrieve values for the `user.id` field, all fields starting with `http.response.`, and the `@timestamp` field.
3939

@@ -69,7 +69,7 @@ By default, document metadata fields like `_id` or `_index` are not returned whe
6969

7070

7171

72-
#### Response always returns an array [search-fields-response]
72+
### Response always returns an array [search-fields-response]
7373

7474
The `fields` response always returns an array of values for each field, even when there is a single value in the `_source`. This is because {{es}} has no dedicated array type, and any field could contain multiple values. The `fields` parameter also does not guarantee that array values are returned in a specific order. See the mapping documentation on [arrays](/reference/elasticsearch/mapping-reference/array.md) for more background.
7575

@@ -109,7 +109,7 @@ The response includes values as a flat list in the `fields` section for each hit
109109
```
110110

111111

112-
#### Retrieve nested fields [search-fields-nested]
112+
### Retrieve nested fields [search-fields-nested]
113113

114114
::::{dropdown}
115115
The `fields` response for [`nested` fields](/reference/elasticsearch/mapping-reference/nested.md) is slightly different from that of regular object fields. While leaf values inside regular `object` fields are returned as a flat list, values inside `nested` fields are grouped to maintain the independence of each object inside the original nested array. For each entry inside a nested field array, values are again returned as a flat list unless there are other `nested` fields inside the parent nested object, in which case the same procedure is repeated again for the deeper nested fields.
@@ -246,7 +246,7 @@ However, when the `fields` pattern targets the nested `user` field directly, no
246246

247247

248248

249-
#### Retrieve unmapped fields [retrieve-unmapped-fields]
249+
### Retrieve unmapped fields [retrieve-unmapped-fields]
250250

251251
::::{dropdown}
252252
By default, the `fields` parameter returns only values of mapped fields. However, {{es}} allows storing fields in `_source` that are unmapped, such as setting [dynamic field mapping](docs-content://manage-data/data-store/mapping/dynamic-field-mapping.md) to `false` or by using an object field with `enabled: false`. These options disable parsing and indexing of the object content.
@@ -326,7 +326,7 @@ The response will contain field results under the `session_data.object.*` path,
326326

327327

328328

329-
#### Ignored field values [ignored-field-values]
329+
### Ignored field values [ignored-field-values]
330330

331331
::::{dropdown}
332332
The `fields` section of the response only returns values that were valid when indexed. If your search request asks for values from a field that ignored certain values because they were malformed or too large these values are returned separately in an `ignored_field_values` section.
@@ -578,6 +578,7 @@ Also only leaf fields can be returned via the `stored_fields` option. If an obje
578578
On its own, `stored_fields` cannot be used to load fields in nested objects — if a field contains a nested object in its path, then no data will be returned for that stored field. To access nested fields, `stored_fields` must be used within an [`inner_hits`](/reference/elasticsearch/rest-apis/retrieve-inner-hits.md) block.
579579
::::
580580

581+
For an example that uses the `stored_fields` parameter, refer to [](retrieve-stored-fields.md).
581582

582583

583584
##### Disable stored fields [disable-stored-fields]
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
---
2+
navigation_title: "Retrieve stored fields"
3+
mapped_pages:
4+
- https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html
5+
applies_to:
6+
stack: all
7+
---
8+
9+
# Retrieve stored fields using the Get document API [get-stored-fields]
10+
11+
Use the `stored_fields` query parameter in a [Get document](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-get) API request to retrieve fields marked as stored (`"store": true`) in the index mapping.
12+
13+
Fields not marked as stored are excluded from the response, even if specified in the request.
14+
15+
::::{tip}
16+
In most cases, the [`fields`](retrieve-selected-fields.md#search-fields-param) and [`_source`](retrieve-selected-fields.md#source-filtering) parameters produce better results than `stored_fields`.
17+
::::
18+
19+
For example, these PUT requests define a stored field in the mapping and add a document:
20+
21+
```console
22+
PUT my-index-000001
23+
{
24+
"mappings": {
25+
"properties": {
26+
"counter": {
27+
"type": "integer",
28+
"store": false
29+
},
30+
"tags": {
31+
"type": "keyword",
32+
"store": true
33+
}
34+
}
35+
}
36+
}
37+
```
38+
39+
```console
40+
PUT my-index-000001/_doc/1
41+
{
42+
"counter": 1,
43+
"tags": [ "production" ]
44+
}
45+
```
46+
47+
% TEST[continued]
48+
49+
This request retrieves the stored fields from the document:
50+
51+
```console
52+
GET my-index-000001/_doc/1?stored_fields=tags,counter
53+
```
54+
55+
% TEST[continued]
56+
57+
The API returns the following response:
58+
59+
```console-result
60+
{
61+
"_index": "my-index-000001",
62+
"_id": "1",
63+
"_version": 1,
64+
"_seq_no": 22,
65+
"_primary_term": 1,
66+
"found": true,
67+
"fields": {
68+
"tags": [
69+
"production"
70+
]
71+
}
72+
}
73+
```
74+
75+
% TESTRESPONSE[s/"_seq_no" : \d+/"_seq_no" : $body._seq_no/ s/"_primary_term" : 1/"_primary_term" : $body._primary_term/]
76+
77+
Although the `counter` field is specified in the request, it's not included in the response because it's not actually a stored field.
78+
79+
Field values are returned as an array.
80+
81+
::::{note}
82+
Only leaf fields can be retrieved with the `stored_fields` parameter. If you specify an object field instead, an error is returned.
83+
::::
84+

docs/reference/elasticsearch/toc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ toc:
9393
- file: rest-apis/reindex-indices.md
9494
- file: rest-apis/retrieve-inner-hits.md
9595
- file: rest-apis/retrieve-selected-fields.md
96+
- file: rest-apis/retrieve-stored-fields.md
9697
- file: rest-apis/retrievers.md
9798
- file: rest-apis/search-multiple-data-streams-indices.md
9899
- file: rest-apis/search-profile.md

libs/simdvec/src/main/java/org/elasticsearch/simdvec/ES91OSQVectorsScorer.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,10 @@ public void quantizeScoreBulk(byte[] q, int count, float[] scores) throws IOExce
9595
* Computes the score by applying the necessary corrections to the provided quantized distance.
9696
*/
9797
public float score(
98-
OptimizedScalarQuantizer.QuantizationResult queryCorrections,
98+
float queryLowerInterval,
99+
float queryUpperInterval,
100+
int queryComponentSum,
101+
float queryAdditionalCorrection,
99102
VectorSimilarityFunction similarityFunction,
100103
float centroidDp,
101104
float lowerInterval,
@@ -107,19 +110,19 @@ public float score(
107110
float ax = lowerInterval;
108111
// Here we assume `lx` is simply bit vectors, so the scaling isn't necessary
109112
float lx = upperInterval - ax;
110-
float ay = queryCorrections.lowerInterval();
111-
float ly = (queryCorrections.upperInterval() - ay) * FOUR_BIT_SCALE;
112-
float y1 = queryCorrections.quantizedComponentSum();
113+
float ay = queryLowerInterval;
114+
float ly = (queryUpperInterval - ay) * FOUR_BIT_SCALE;
115+
float y1 = queryComponentSum;
113116
float score = ax * ay * dimensions + ay * lx * (float) targetComponentSum + ax * ly * y1 + lx * ly * qcDist;
114117
// For euclidean, we need to invert the score and apply the additional correction, which is
115118
// assumed to be the squared l2norm of the centroid centered vectors.
116119
if (similarityFunction == EUCLIDEAN) {
117-
score = queryCorrections.additionalCorrection() + additionalCorrection - 2 * score;
120+
score = queryAdditionalCorrection + additionalCorrection - 2 * score;
118121
return Math.max(1 / (1f + score), 0);
119122
} else {
120123
// For cosine and max inner product, we need to apply the additional correction, which is
121124
// assumed to be the non-centered dot-product between the vector and the centroid
122-
score += queryCorrections.additionalCorrection() + additionalCorrection - centroidDp;
125+
score += queryAdditionalCorrection + additionalCorrection - centroidDp;
123126
if (similarityFunction == MAXIMUM_INNER_PRODUCT) {
124127
return VectorUtil.scaleMaxInnerProductScore(score);
125128
}
@@ -140,7 +143,10 @@ public float score(
140143
*/
141144
public void scoreBulk(
142145
byte[] q,
143-
OptimizedScalarQuantizer.QuantizationResult queryCorrections,
146+
float queryLowerInterval,
147+
float queryUpperInterval,
148+
int queryComponentSum,
149+
float queryAdditionalCorrection,
144150
VectorSimilarityFunction similarityFunction,
145151
float centroidDp,
146152
float[] scores
@@ -154,7 +160,10 @@ public void scoreBulk(
154160
in.readFloats(additionalCorrections, 0, BULK_SIZE);
155161
for (int i = 0; i < BULK_SIZE; i++) {
156162
scores[i] = score(
157-
queryCorrections,
163+
queryLowerInterval,
164+
queryUpperInterval,
165+
queryComponentSum,
166+
queryAdditionalCorrection,
158167
similarityFunction,
159168
centroidDp,
160169
lowerIntervals[i],

0 commit comments

Comments
 (0)