Skip to content

Commit 9c9ba9d

Browse files
authored
Merge branch 'main' into ass-stats
2 parents 3e582a5 + ce8dc14 commit 9c9ba9d

File tree

58 files changed

+472
-399
lines changed

Some content is hidden

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

58 files changed

+472
-399
lines changed

docs/changelog/127199.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 127199
2+
summary: Disable a bugged commit
3+
area: ES|QL
4+
type: bug
5+
issues:
6+
- 127197

docs/reference/elasticsearch/mapping-reference/dense-vector.md

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ mapped_pages:
66

77
# Dense vector field type [dense-vector]
88

9-
109
The `dense_vector` field type stores dense vectors of numeric values. Dense vector fields are primarily used for [k-nearest neighbor (kNN) search](docs-content://deploy-manage/production-guidance/optimize-performance/approximate-knn-search.md).
1110

1211
The `dense_vector` type does not support aggregations or sorting.
@@ -46,7 +45,6 @@ PUT my-index/_doc/2
4645
Unlike most other data types, dense vectors are always single-valued. It is not possible to store multiple values in one `dense_vector` field.
4746
::::
4847

49-
5048
## Index vectors for kNN search [index-vectors-knn-search]
5149

5250
A *k-nearest neighbor* (kNN) search finds the *k* nearest vectors to a query vector, as measured by a similarity metric.
@@ -78,7 +76,6 @@ PUT my-index-2
7876
Indexing vectors for approximate kNN search is an expensive process. It can take substantial time to ingest documents that contain vector fields with `index` enabled. See [k-nearest neighbor (kNN) search](docs-content://deploy-manage/production-guidance/optimize-performance/approximate-knn-search.md) to learn more about the memory requirements.
7977
::::
8078

81-
8279
You can disable indexing by setting the `index` parameter to `false`:
8380

8481
```console
@@ -98,7 +95,6 @@ PUT my-index-2
9895

9996
{{es}} uses the [HNSW algorithm](https://arxiv.org/abs/1603.09320) to support efficient kNN search. Like most kNN algorithms, HNSW is an approximate method that sacrifices result accuracy for improved speed.
10097

101-
10298
## Automatically quantize vectors for kNN search [dense-vector-quantization]
10399

104100
The `dense_vector` type supports quantization to reduce the memory footprint required when [searching](docs-content://solutions/search/vector/knn.md#approximate-knn) `float` vectors. The three following quantization strategies are supported:
@@ -117,17 +113,14 @@ Quantized vectors can use [oversampling and rescoring](docs-content://solutions/
117113
Quantization will continue to keep the raw float vector values on disk for reranking, reindexing, and quantization improvements over the lifetime of the data. This means disk usage will increase by ~25% for `int8`, ~12.5% for `int4`, and ~3.1% for `bbq` due to the overhead of storing the quantized and raw vectors.
118114
::::
119115

120-
121116
::::{note}
122117
`int4` quantization requires an even number of vector dimensions.
123118
::::
124119

125-
126120
::::{note}
127121
`bbq` quantization only supports vector dimensions that are greater than 64.
128122
::::
129123

130-
131124
Here is an example of how to create a byte-quantized index:
132125

133126
```console
@@ -188,7 +181,6 @@ PUT my-byte-quantized-index
188181
}
189182
```
190183

191-
192184
## Parameters for dense vector fields [dense-vector-params]
193185

194186
The following mapping parameters are accepted:
@@ -210,7 +202,6 @@ $$$dense-vector-element-type$$$
210202

211203
::::
212204

213-
214205
`dims`
215206
: (Optional, integer) Number of vector dimensions. Can’t exceed `4096`. If `dims` is not specified, it will be set to the length of the first vector added to the field.
216207

@@ -228,7 +219,6 @@ $$$dense-vector-similarity$$$
228219
`bit` vectors only support `l2_norm` as their similarity metric.
229220
::::
230221

231-
232222
::::{dropdown} Valid values for `similarity`
233223
`l2_norm`
234224
: Computes similarity based on the L2 distance (also known as Euclidean distance) between the vectors. The document `_score` is computed as `1 / (1 + l2_norm(query, vector)^2)`.
@@ -242,7 +232,6 @@ For `bit` vectors, instead of using `l2_norm`, the `hamming` distance between th
242232

243233
When `element_type` is `byte`, all vectors must have the same length including both document and query vectors or results will be inaccurate. The document `_score` is computed as `0.5 + (dot_product(query, vector) / (32768 * dims))` where `dims` is the number of dimensions per vector.
244234

245-
246235
`cosine`
247236
: Computes the cosine similarity. During indexing {{es}} automatically normalizes vectors with `cosine` similarity to unit length. This allows to internally use `dot_product` for computing similarity, which is more efficient. Original un-normalized vectors can be still accessed through scripts. The document `_score` is computed as `(1 + cosine(query, vector)) / 2`. The `cosine` similarity does not allow vectors with zero magnitude, since cosine is not defined in this case.
248237

@@ -251,12 +240,10 @@ For `bit` vectors, instead of using `l2_norm`, the `hamming` distance between th
251240

252241
::::
253242

254-
255243
::::{note}
256244
Although they are conceptually related, the `similarity` parameter is different from [`text`](/reference/elasticsearch/mapping-reference/text.md) field [`similarity`](/reference/elasticsearch/mapping-reference/similarity.md) and accepts a distinct set of options.
257245
::::
258246

259-
260247
$$$dense-vector-index-options$$$
261248

262249
`index_options`
@@ -267,7 +254,6 @@ $$$dense-vector-index-options$$$
267254
::::{dropdown} Properties of `index_options`
268255
`type`
269256
: (Required, string) The type of kNN algorithm to use. Can be either any of:
270-
271257
* `hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) for scalable approximate kNN search. This supports all `element_type` values.
272258
* `int8_hnsw` - The default index type for float vectors. This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float`. This can reduce the memory footprint by 4x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization).
273259
* `int4_hnsw` - This utilizes the [HNSW algorithm](https://arxiv.org/abs/1603.09320) in addition to automatically scalar quantization for scalable approximate kNN search with `element_type` of `float`. This can reduce the memory footprint by 8x at the cost of some accuracy. See [Automatically quantize vectors for kNN search](#dense-vector-quantization).
@@ -276,17 +262,17 @@ $$$dense-vector-index-options$$$
276262
* `int8_flat` - This utilizes a brute-force search algorithm in addition to automatically scalar quantization. Only supports `element_type` of `float`.
277263
* `int4_flat` - This utilizes a brute-force search algorithm in addition to automatically half-byte scalar quantization. Only supports `element_type` of `float`.
278264
* `bbq_flat` - This utilizes a brute-force search algorithm in addition to automatically binary quantization. Only supports `element_type` of `float`.
279-
280-
265+
281266
`m`
282267
: (Optional, integer) The number of neighbors each node will be connected to in the HNSW graph. Defaults to `16`. Only applicable to `hnsw`, `int8_hnsw`, `int4_hnsw` and `bbq_hnsw` index types.
283-
268+
284269
`ef_construction`
285270
: (Optional, integer) The number of candidates to track while assembling the list of nearest neighbors for each new node. Defaults to `100`. Only applicable to `hnsw`, `int8_hnsw`, `int4_hnsw` and `bbq_hnsw` index types.
286-
271+
287272
`confidence_interval`
288273
: (Optional, float) Only applicable to `int8_hnsw`, `int4_hnsw`, `int8_flat`, and `int4_flat` index types. The confidence interval to use when quantizing the vectors. Can be any value between and including `0.90` and `1.0` or exactly `0`. When the value is `0`, this indicates that dynamic quantiles should be calculated for optimized quantization. When between `0.90` and `1.0`, this value restricts the values used when calculating the quantization thresholds. For example, a value of `0.95` will only use the middle 95% of the values when calculating the quantization thresholds (e.g. the highest and lowest 2.5% of values will be ignored). Defaults to `1/(dims + 1)` for `int8` quantized vectors and `0` for `int4` for dynamic quantile calculation.
289274

275+
290276
`rescore_vector`
291277
: (Optional, object) An optional section that configures automatic vector rescoring on knn queries for the given field. Only applicable to quantized index types.
292278
:::::{dropdown} Properties of `rescore_vector`

docs/reference/query-languages/esql/_snippets/commands/layout/lookup-join.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ SLA of official GA features.
1111
index, to your {{esql}} query results, simplifying data enrichment
1212
and analysis workflows.
1313

14+
Refer to [the high-level landing page](../../../../esql/esql-lookup-join.md) for an overview of the `LOOKUP JOIN` command, including use cases, prerequisites, and current limitations.
15+
1416
**Syntax**
1517

1618
```esql
@@ -21,18 +23,14 @@ FROM <source_index>
2123
**Parameters**
2224

2325
`<lookup_index>`
24-
: The name of the lookup index. This must be a specific index name - wildcards, aliases, and remote cluster
25-
references are not supported.
26+
: The name of the lookup index. This must be a specific index name - wildcards, aliases, and remote cluster references are not supported. Indices used for lookups must be configured with the [`lookup` index mode](/reference/elasticsearch/index-settings/index-modules.md#index-mode-setting).
2627

2728
`<field_name>`
28-
: The field to join on. This field must exist
29-
in both your current query results and in the lookup index. If the field
30-
contains multi-valued entries, those entries will not match anything
31-
(the added fields will contain `null` for those rows).
29+
: The field to join on. This field must exist in both your current query results and in the lookup index. If the field contains multi-valued entries, those entries will not match anything (the added fields will contain `null` for those rows).
3230

3331
**Description**
3432

35-
The `LOOKUP JOIN` command adds new columns to your {esql} query
33+
The `LOOKUP JOIN` command adds new columns to your {{esql}} query
3634
results table by finding documents in a lookup index that share the same
3735
join field value as your result rows.
3836

docs/reference/query-languages/esql/esql-lookup-join.md

Lines changed: 99 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ For example, you can use `LOOKUP JOIN` to:
1616
* Quickly see if any source IPs match known malicious addresses.
1717
* Tag logs with the owning team or escalation info for faster triage and incident response.
1818

19-
[`LOOKUP join`](/reference/query-languages/esql/commands/processing-commands.md#esql-lookup-join) is similar to [`ENRICH`](/reference/query-languages/esql/commands/processing-commands.md#esql-enrich) in the fact that they both help you join data together. You should use `LOOKUP JOIN` when:
19+
## Compare with `ENRICH`
20+
21+
[`LOOKUP JOIN`](/reference/query-languages/esql/commands/processing-commands.md#esql-lookup-join) is similar to [`ENRICH`](/reference/query-languages/esql/commands/processing-commands.md#esql-enrich) in the fact that they both help you join data together. You should use `LOOKUP JOIN` when:
2022

2123
* Your enrichment data changes frequently
2224
* You want to avoid index-time processing
@@ -26,82 +28,119 @@ For example, you can use `LOOKUP JOIN` to:
2628
* You want to restrict users to use only specific lookup indices
2729
* You do not need to match using ranges or spatial relations
2830

29-
## How the `LOOKUP JOIN` command works [esql-how-lookup-join-works]
31+
## How the command works [esql-how-lookup-join-works]
32+
33+
The `LOOKUP JOIN` command adds fields from the lookup index as new columns to your results table based on matching values in the join field.
34+
35+
The command requires two parameters:
36+
- The name of the lookup index (which must have the `lookup` [`index.mode setting`](/reference/elasticsearch/index-settings/index-modules.md#index-mode-setting))
37+
- The name of the field to join on
3038

31-
The `LOOKUP JOIN` command adds new columns to a table, with data from {{es}} indices.
39+
```esql
40+
LOOKUP JOIN <lookup_index> ON <field_name>
41+
```
3242

3343
:::{image} ../images/esql-lookup-join.png
34-
:alt: esql lookup join
44+
:alt: Illustration of the `LOOKUP JOIN` command, where the input table is joined with a lookup index to create an enriched output table.
3545
:::
3646

37-
`<lookup_index>`
38-
: The name of the lookup index. This must be a specific index name - wildcards, aliases, and remote cluster references are not supported. Indices used for lookups must be configured with the [`lookup` index mode](/reference/elasticsearch/index-settings/index-modules.md#index-mode-setting).
39-
40-
`<field_name>`
41-
: The field to join on. This field must exist in both your current query results and in the lookup index. If the field contains multi-valued entries, those entries will not match anything (the added fields will contain `null` for those rows).
47+
If you're familiar with SQL, `LOOKUP JOIN` has left-join behavior. This means that if no rows match in the lookup index, the incoming row is retained and `null`s are added. If many rows in the lookup index match, `LOOKUP JOIN` adds one row per match.
4248

4349
## Example
4450

45-
`LOOKUP JOIN` has left-join behavior. If no rows match in the lookup index, `LOOKUP JOIN` retains the incoming row and adds `null`s. If many rows in the lookup index match, `LOOKUP JOIN` adds one row per match.
46-
47-
In this example, we have two sample tables:
51+
You can run this example for yourself if you'd like to see how it works, by setting up the indices and adding sample data.
52+
53+
### Sample data
54+
:::{dropdown} Expand for setup instructions
55+
56+
**Set up indices**
57+
58+
First let's create two indices with mappings: `threat_list` and `firewall_logs`.
59+
60+
```console
61+
PUT threat_list
62+
{
63+
"settings": {
64+
"index.mode": "lookup" # The lookup index must use this mode
65+
},
66+
"mappings": {
67+
"properties": {
68+
"source.ip": { "type": "ip" },
69+
"threat_level": { "type": "keyword" },
70+
"threat_type": { "type": "keyword" },
71+
"last_updated": { "type": "date" }
72+
}
73+
}
74+
}
75+
```
76+
```console
77+
PUT firewall_logs
78+
{
79+
"mappings": {
80+
"properties": {
81+
"timestamp": { "type": "date" },
82+
"source.ip": { "type": "ip" },
83+
"destination.ip": { "type": "ip" },
84+
"action": { "type": "keyword" },
85+
"bytes_transferred": { "type": "long" }
86+
}
87+
}
88+
}
89+
```
4890

49-
**employees**
91+
**Add sample data**
5092

51-
| birth_date|emp_no|first_name|gender|hire_date|language|
52-
|---|---|---|---|---|---|
53-
|1955-10-04T00:00:00Z|10091|Amabile |M|1992-11-18T00:00:00Z|3|
54-
|1964-10-18T00:00:00Z|10092|Valdiodio |F|1989-09-22T00:00:00Z|1|
55-
|1964-06-11T00:00:00Z|10093|Sailaja |M|1996-11-05T00:00:00Z|3|
56-
|1957-05-25T00:00:00Z|10094|Arumugam |F|1987-04-18T00:00:00Z|5|
57-
|1965-01-03T00:00:00Z|10095|Hilari |M|1986-07-15T00:00:00Z|4|
93+
Next, let's add some sample data to both indices. The `threat_list` index contains known malicious IPs, while the `firewall_logs` index contains logs of network traffic.
5894

59-
**languages_non_unique_key**
95+
```console
96+
POST threat_list/_bulk
97+
{"index":{}}
98+
{"source.ip":"203.0.113.5","threat_level":"high","threat_type":"C2_SERVER","last_updated":"2025-04-22"}
99+
{"index":{}}
100+
{"source.ip":"198.51.100.2","threat_level":"medium","threat_type":"SCANNER","last_updated":"2025-04-23"}
101+
```
60102

61-
|language_code|language_name|country|
62-
|---|---|---|
63-
|1|English|Canada|
64-
|1|English|
65-
|1||United Kingdom|
66-
|1|English|United States of America|
67-
|2|German|[Germany\|Austria]|
68-
|2|German|Switzerland|
69-
|2|German|
70-
|4|Spanish|
71-
|5||France|
72-
|[6\|7]|Mv-Lang|Mv-Land|
73-
|[7\|8]|Mv-Lang2|Mv-Land2|
74-
||Null-Lang|Null-Land|
75-
||Null-Lang2|Null-Land2|
103+
```console
104+
POST firewall_logs/_bulk
105+
{"index":{}}
106+
{"timestamp":"2025-04-23T10:00:01Z","source.ip":"192.0.2.1","destination.ip":"10.0.0.100","action":"allow","bytes_transferred":1024}
107+
{"index":{}}
108+
{"timestamp":"2025-04-23T10:00:05Z","source.ip":"203.0.113.5","destination.ip":"10.0.0.55","action":"allow","bytes_transferred":2048}
109+
{"index":{}}
110+
{"timestamp":"2025-04-23T10:00:08Z","source.ip":"198.51.100.2","destination.ip":"10.0.0.200","action":"block","bytes_transferred":0}
111+
{"index":{}}
112+
{"timestamp":"2025-04-23T10:00:15Z","source.ip":"203.0.113.5","destination.ip":"10.0.0.44","action":"allow","bytes_transferred":4096}
113+
{"index":{}}
114+
{"timestamp":"2025-04-23T10:00:30Z","source.ip":"192.0.2.1","destination.ip":"10.0.0.100","action":"allow","bytes_transferred":512}
115+
```
116+
:::
76117

77-
Running the following query would provide the results shown below.
118+
### Query the data
78119

79120
```esql
80-
FROM employees
81-
| EVAL language_code = emp_no % 10
82-
| LOOKUP JOIN languages_lookup_non_unique_key ON language_code
83-
| WHERE emp_no > 10090 AND emp_no < 10096
84-
| SORT emp_no, country
85-
| KEEP emp_no, language_code, language_name, country;
121+
FROM firewall_logs # The source index
122+
| LOOKUP JOIN threat_list ON source.ip # The lookup index and join field
123+
| WHERE threat_level IS NOT NULL # Filter for rows non-null threat levels
124+
| SORT timestamp # LOOKUP JOIN does not guarantee output order, so you must explicitly sort the results if needed
125+
| KEEP timestamp, source.ip, destination.ip, action, threat_level, threat_type # Keep only relevant fields
126+
| LIMIT 10 # Limit the output to 10 rows
86127
```
87128

88-
|emp_no|language_code|language_name|country|
89-
|---|---|---|---|
90-
| 10091 | 1 | English | Canada|
91-
| 10091 | 1 | null | United Kingdom|
92-
| 10091 | 1 | English | United States of America|
93-
| 10091 | 1 | English | null|
94-
| 10092 | 2 | German | [Germany, Austria]|
95-
| 10092 | 2 | German | Switzerland|
96-
| 10092 | 2 | German | null|
97-
| 10093 | 3 | null | null|
98-
| 10094 | 4 | Spanish | null|
99-
| 10095 | 5 | null | France|
100-
101-
::::{important}
102-
`LOOKUP JOIN` does not guarantee the output to be in any particular order. If a certain order is required, users should use a [`SORT`](/reference/query-languages/esql/commands/processing-commands.md#esql-sort) somewhere after the `LOOKUP JOIN`.
103-
104-
::::
129+
### Response
130+
131+
A successful query will output a table. In this example, you can see that the `source.ip` field from the `firewall_logs` index is matched with the `source.ip` field in the `threat_list` index, and the corresponding `threat_level` and `threat_type` fields are added to the output.
132+
133+
```
134+
source.ip | action | threat_type | threat_level
135+
---------------+---------------+---------------+---------------
136+
203.0.113.5 |allow |C2_SERVER |high
137+
198.51.100.2 |block |SCANNER |medium
138+
203.0.113.5 |allow |C2_SERVER |high
139+
```
140+
141+
### Additional examples
142+
143+
Refer to the examples section of the [`LOOKUP JOIN`](/reference/query-languages/esql/commands/processing-commands.md#esql-lookup-join) command reference for more examples.
105144

106145
## Prerequisites [esql-lookup-join-prereqs]
107146

modules/data-streams/src/internalClusterTest/java/org/elasticsearch/datastreams/DataStreamIT.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1384,7 +1384,9 @@ public void testSearchAllResolvesDataStreams() throws Exception {
13841384

13851385
public void testGetDataStream() throws Exception {
13861386
Settings settings = Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, maximumNumberOfReplicas() + 2).build();
1387-
DataStreamLifecycle.Template lifecycle = DataStreamLifecycle.builder().dataRetention(randomPositiveTimeValue()).buildTemplate();
1387+
DataStreamLifecycle.Template lifecycle = DataStreamLifecycle.dataLifecycleBuilder()
1388+
.dataRetention(randomPositiveTimeValue())
1389+
.buildTemplate();
13881390
putComposableIndexTemplate("template_for_foo", null, List.of("metrics-foo*"), settings, null, null, lifecycle, false);
13891391
int numDocsFoo = randomIntBetween(2, 16);
13901392
indexDocs("metrics-foo", numDocsFoo);

0 commit comments

Comments
 (0)