Skip to content

Commit 75ca874

Browse files
authored
ES|QL brute force l1_norm vector function (#131768)
1 parent ad63aaf commit 75ca874

File tree

16 files changed

+323
-8
lines changed

16 files changed

+323
-8
lines changed

docs/reference/query-languages/esql/_snippets/functions/description/v_l1_norm.md

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/_snippets/functions/examples/v_l1_norm.md

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/_snippets/functions/layout/v_l1_norm.md

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/_snippets/functions/parameters/v_l1_norm.md

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/images/functions/v_l1_norm.svg

Lines changed: 1 addition & 0 deletions
Loading

docs/reference/query-languages/esql/kibana/definition/functions/v_l1_norm.json

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/query-languages/esql/kibana/docs/functions/v_l1_norm.md

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Tests for l1_norm similarity function
2+
3+
similarityWithVectorField
4+
required_capability: l1_norm_vector_similarity_function
5+
6+
// tag::vector-l1-norm-similarity[]
7+
from colors
8+
| eval similarity = v_l1_norm(rgb_vector, [0, 255, 255])
9+
| sort similarity desc, color asc
10+
// end::vector-l1-norm-similarity[]
11+
| limit 10
12+
| keep color, similarity
13+
;
14+
15+
// tag::vector-l1-norm-similarity-result[]
16+
color:text | similarity:double
17+
red | 765.0
18+
crimson | 650.0
19+
maroon | 638.0
20+
firebrick | 620.0
21+
orange | 600.0
22+
tomato | 595.0
23+
brown | 591.0
24+
chocolate | 585.0
25+
coral | 558.0
26+
gold | 550.0
27+
// end::vector-l1-norm-similarity-result[]
28+
;
29+
30+
similarityAsPartOfExpression
31+
required_capability: l1_norm_vector_similarity_function
32+
33+
from colors
34+
| eval score = round((1 + v_l1_norm(rgb_vector, [0, 255, 255]) / 2), 3)
35+
| sort score desc, color asc
36+
| limit 10
37+
| keep color, score
38+
;
39+
40+
color:text | score:double
41+
red | 383.5
42+
crimson | 326.0
43+
maroon | 320.0
44+
firebrick | 311.0
45+
orange | 301.0
46+
tomato | 298.5
47+
brown | 296.5
48+
chocolate | 293.5
49+
coral | 280.0
50+
gold | 276.0
51+
;
52+
53+
similarityWithLiteralVectors
54+
required_capability: l1_norm_vector_similarity_function
55+
56+
row a = 1
57+
| eval similarity = round(v_l1_norm([1, 2, 3], [0, 1, 2]), 3)
58+
| keep similarity
59+
;
60+
61+
similarity:double
62+
3.0
63+
;
64+
65+
similarityWithStats
66+
required_capability: l1_norm_vector_similarity_function
67+
68+
from colors
69+
| eval similarity = round(v_l1_norm(rgb_vector, [0, 255, 255]), 3)
70+
| stats avg = round(avg(similarity), 3), min = min(similarity), max = max(similarity)
71+
;
72+
73+
avg:double | min:double | max:double
74+
391.254 | 0.0 | 765.0
75+
;
76+
77+
# TODO Need to implement a conversion function to convert a non-foldable row to a dense_vector
78+
similarityWithRow-Ignore
79+
required_capability: l1_norm_vector_similarity_function
80+
81+
row vector = [1, 2, 3]
82+
| eval similarity = round(v_l1_norm(vector, [0, 1, 2]), 3)
83+
| sort similarity desc, color asc
84+
| limit 10
85+
| keep color, similarity
86+
;
87+
88+
similarity:double
89+
0.978
90+
;

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/vector/VectorSimilarityFunctionsIT.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import org.elasticsearch.xpack.esql.EsqlTestUtils;
2121
import org.elasticsearch.xpack.esql.action.AbstractEsqlIntegTestCase;
2222
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
23+
import org.elasticsearch.xpack.esql.expression.function.vector.L1Norm;
24+
import org.elasticsearch.xpack.esql.expression.function.vector.VectorSimilarityFunction.SimilarityEvaluatorFunction;
2325
import org.junit.Before;
2426

2527
import java.io.IOException;
@@ -37,22 +39,25 @@ public static Iterable<Object[]> parameters() throws Exception {
3739
List<Object[]> params = new ArrayList<>();
3840

3941
if (EsqlCapabilities.Cap.COSINE_VECTOR_SIMILARITY_FUNCTION.isEnabled()) {
40-
params.add(new Object[] { "v_cosine", VectorSimilarityFunction.COSINE });
42+
params.add(new Object[] { "v_cosine", (SimilarityEvaluatorFunction) VectorSimilarityFunction.COSINE::compare });
4143
}
4244
if (EsqlCapabilities.Cap.DOT_PRODUCT_VECTOR_SIMILARITY_FUNCTION.isEnabled()) {
43-
params.add(new Object[] { "v_dot_product", VectorSimilarityFunction.DOT_PRODUCT });
45+
params.add(new Object[] { "v_dot_product", (SimilarityEvaluatorFunction) VectorSimilarityFunction.DOT_PRODUCT::compare });
46+
}
47+
if (EsqlCapabilities.Cap.L1_NORM_VECTOR_SIMILARITY_FUNCTION.isEnabled()) {
48+
params.add(new Object[] { "v_l1_norm", (SimilarityEvaluatorFunction) L1Norm::calculateSimilarity });
4449
}
4550

4651
return params;
4752
}
4853

4954
private final String functionName;
50-
private final VectorSimilarityFunction similarityFunction;
55+
private final SimilarityEvaluatorFunction similarityFunction;
5156
private int numDims;
5257

5358
public VectorSimilarityFunctionsIT(
5459
@Name("functionName") String functionName,
55-
@Name("similarityFunction") VectorSimilarityFunction similarityFunction
60+
@Name("similarityFunction") SimilarityEvaluatorFunction similarityFunction
5661
) {
5762
this.functionName = functionName;
5863
this.similarityFunction = similarityFunction;
@@ -74,7 +79,7 @@ public void testSimilarityBetweenVectors() {
7479
Double similarity = (Double) values.get(2);
7580

7681
assertNotNull(similarity);
77-
float expectedSimilarity = similarityFunction.compare(left, right);
82+
float expectedSimilarity = similarityFunction.calculateSimilarity(left, right);
7883
assertEquals(expectedSimilarity, similarity, 0.0001);
7984
});
8085
}
@@ -96,7 +101,7 @@ public void testSimilarityBetweenConstantVectorAndField() {
96101
Double similarity = (Double) values.get(1);
97102

98103
assertNotNull(similarity);
99-
float expectedSimilarity = similarityFunction.compare(left, randomVector);
104+
float expectedSimilarity = similarityFunction.calculateSimilarity(left, randomVector);
100105
assertEquals(expectedSimilarity, similarity, 0.0001);
101106
});
102107
}
@@ -130,7 +135,7 @@ public void testSimilarityBetweenConstantVectors() {
130135

131136
Double similarity = (Double) valuesList.get(0).get(0);
132137
assertNotNull(similarity);
133-
float expectedSimilarity = similarityFunction.compare(vectorLeft, vectorRight);
138+
float expectedSimilarity = similarityFunction.calculateSimilarity(vectorLeft, vectorRight);
134139
assertEquals(expectedSimilarity, similarity, 0.0001);
135140
}
136141
}

x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,11 @@ public enum Cap {
12961296
*/
12971297
DOT_PRODUCT_VECTOR_SIMILARITY_FUNCTION(Build.current().isSnapshot()),
12981298

1299+
/**
1300+
* l1 norm vector similarity function
1301+
*/
1302+
L1_NORM_VECTOR_SIMILARITY_FUNCTION(Build.current().isSnapshot()),
1303+
12991304
/**
13001305
* Support for the options field of CATEGORIZE.
13011306
*/

0 commit comments

Comments
 (0)