@@ -36,6 +36,10 @@ GET /_search
3636// CONSOLE
3737// TEST[setup:twitter]
3838
39+ NOTE: The values returned from `script_score` cannot be negative. In general,
40+ Lucene requires the scores produced by queries to be non-negative in order to
41+ support certain search optimizations.
42+
3943==== Accessing the score of a document within a script
4044
4145Within a script, you can
@@ -92,17 +96,18 @@ cosine similarity between a given query vector and document vectors.
9296 "match_all": {}
9397 },
9498 "script": {
95- "source": "cosineSimilarity(params.queryVector , doc['my_dense_vector'])" ,
99+ "source": "cosineSimilarity(params.query_vector , doc['my_dense_vector']) + 1.0" <1> ,
96100 "params": {
97- "queryVector ": [4, 3.4, -0.2] <1 >
101+ "query_vector ": [4, 3.4, -0.2] <2 >
98102 }
99103 }
100104 }
101105 }
102106}
103107--------------------------------------------------
104108// NOTCONSOLE
105- <1> To take advantage of the script optimizations, provide a query vector as a script parameter.
109+ <1> The script adds 1.0 to the cosine similarity to prevent the score from being negative.
110+ <2> To take advantage of the script optimizations, provide a query vector as a script parameter.
106111
107112Similarly, for sparse_vector fields, `cosineSimilaritySparse` calculates cosine similarity
108113between a given query vector and document vectors.
@@ -116,9 +121,9 @@ between a given query vector and document vectors.
116121 "match_all": {}
117122 },
118123 "script": {
119- "source": "cosineSimilaritySparse(params.queryVector , doc['my_sparse_vector'])",
124+ "source": "cosineSimilaritySparse(params.query_vector , doc['my_sparse_vector']) + 1.0 ",
120125 "params": {
121- "queryVector ": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
126+ "query_vector ": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
122127 }
123128 }
124129 }
@@ -139,9 +144,12 @@ dot product between a given query vector and document vectors.
139144 "match_all": {}
140145 },
141146 "script": {
142- "source": "dotProduct(params.queryVector, doc['my_dense_vector'])",
147+ "source": """
148+ double value = dotProduct(params.query_vector, doc['my_vector']);
149+ return sigmoid(1, Math.E, -value); <1>
150+ """,
143151 "params": {
144- "queryVector ": [4, 3.4, -0.2]
152+ "query_vector ": [4, 3.4, -0.2]
145153 }
146154 }
147155 }
@@ -150,6 +158,8 @@ dot product between a given query vector and document vectors.
150158--------------------------------------------------
151159// NOTCONSOLE
152160
161+ <1> Using the standard sigmoid function prevents scores from being negative.
162+
153163Similarly, for sparse_vector fields, `dotProductSparse` calculates dot product
154164between a given query vector and document vectors.
155165
@@ -162,9 +172,12 @@ between a given query vector and document vectors.
162172 "match_all": {}
163173 },
164174 "script": {
165- "source": "dotProductSparse(params.queryVector, doc['my_sparse_vector'])",
166- "params": {
167- "queryVector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
175+ "source": """
176+ double value = dotProductSparse(params.query_vector, doc['my_sparse_vector']);
177+ return sigmoid(1, Math.E, -value);
178+ """,
179+ "params": {
180+ "query_vector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
168181 }
169182 }
170183 }
0 commit comments