Skip to content

Commit dd9c837

Browse files
authored
Deprecates indexing and querying a context completion field without context (#31006)
This change deprecates completion queries and documents without context that target a context enabled completion field. Querying without context degrades the search performance considerably (even when the number of indexed contexts is low). This commit targets master but the deprecation will take place in 6.x and the functionality will be removed in 7 in a follow up. This is a backport of #30712
1 parent 9ff1f8b commit dd9c837

File tree

7 files changed

+103
-19
lines changed

7 files changed

+103
-19
lines changed

docs/reference/migration/migrate_6_0/search.asciidoc

+7-1
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,10 @@ for a particular index with the index setting `index.max_terms_count`.
207207
For 6.x and starting in 6.3 a deprecation warning will be printed to warn
208208
against search requests that contain extra tokens after the main object.
209209
These extra tokens were ignored by the query parser before 6.3 but the next
210-
major version will not accept invalid body anymore.
210+
major version will not accept invalid body anymore.
211+
212+
==== Context suggester without contexts
213+
214+
The ability to query and index context enabled suggestions without contexts
215+
has been deprecated. Context enabled suggestion queries without contexts have
216+
to visit every suggestion, which degrades the search performance considerably.

docs/reference/search/suggesters/context-suggest.asciidoc

+7-3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ PUT place_path_category
8484
NOTE: Adding context mappings increases the index size for completion field. The completion index
8585
is entirely heap resident, you can monitor the completion field index size using <<indices-stats>>.
8686

87+
NOTE: deprecated[7.0.0, Indexing a suggestion without context on a context enabled completion field is deprecated
88+
and will be removed in the next major release. If you want to index a suggestion that matches all contexts you should
89+
add a special context for it.]
90+
8791
[[suggester-context-category]]
8892
[float]
8993
==== Category Context
@@ -156,9 +160,9 @@ POST place/_search?pretty
156160
// CONSOLE
157161
// TEST[continued]
158162

159-
NOTE: When no categories are provided at query-time, all indexed documents are considered.
160-
Querying with no categories on a category enabled completion field should be avoided, as it
161-
will degrade search performance.
163+
Note: deprecated[7.0.0, When no categories are provided at query-time, all indexed documents are considered.
164+
Querying with no categories on a category enabled completion field is deprecated and will be removed in the next major release
165+
as it degrades search performance considerably.]
162166

163167
Suggestions with certain categories can be boosted higher than others.
164168
The following filters suggestions by categories and additionally boosts

rest-api-spec/src/main/resources/rest-api-spec/test/suggest/30_context.yml

+68-4
Original file line numberDiff line numberDiff line change
@@ -336,16 +336,80 @@ setup:
336336
- length: { suggest.result.0.options: 1 }
337337
- match: { suggest.result.0.options.0.text: "foo" }
338338

339+
---
340+
"Indexing and Querying without contexts is deprecated":
341+
- skip:
342+
version: " - 6.3.99"
343+
reason: this feature was deprecated in 6.4
344+
features: "warnings"
345+
346+
- do:
347+
index:
348+
index: test
349+
type: test
350+
id: 1
351+
body:
352+
suggest_context:
353+
input: "foo"
354+
contexts:
355+
color: "red"
356+
suggest_multi_contexts:
357+
input: "bar"
358+
contexts:
359+
color: "blue"
360+
361+
- do:
362+
warnings:
363+
- "The ability to index a suggestion with no context on a context enabled completion field is deprecated and will be removed in the next major release."
364+
index:
365+
index: test
366+
type: test
367+
id: 2
368+
body:
369+
suggest_context:
370+
input: "foo"
371+
372+
- do:
373+
indices.refresh: {}
374+
339375
- do:
340-
search:
376+
warnings:
377+
- "The ability to query with no context on a context enabled completion field is deprecated and will be removed in the next major release."
378+
search:
341379
body:
342380
suggest:
343381
result:
344382
text: "foo"
345383
completion:
346-
skip_duplicates: true
347384
field: suggest_context
348385

349386
- length: { suggest.result: 1 }
350-
- length: { suggest.result.0.options: 1 }
351-
- match: { suggest.result.0.options.0.text: "foo" }
387+
388+
- do:
389+
warnings:
390+
- "The ability to query with no context on a context enabled completion field is deprecated and will be removed in the next major release."
391+
search:
392+
body:
393+
suggest:
394+
result:
395+
text: "foo"
396+
completion:
397+
field: suggest_context
398+
contexts: {}
399+
400+
- length: { suggest.result: 1 }
401+
402+
- do:
403+
warnings:
404+
- "The ability to query with no context on a context enabled completion field is deprecated and will be removed in the next major release."
405+
search:
406+
body:
407+
suggest:
408+
result:
409+
text: "foo"
410+
completion:
411+
field: suggest_multi_contexts
412+
contexts:
413+
location: []
414+
415+
- length: { suggest.result: 1 }

rest-api-spec/src/main/resources/rest-api-spec/test/suggest/40_typed_keys.yml

+4-10
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,19 @@ setup:
2020
-
2121
"name" : "format"
2222
"type" : "category"
23+
---
24+
"Test typed keys parameter for suggesters":
2325

2426
- do:
25-
bulk:
27+
bulk:
2628
refresh: true
2729
index: test
2830
type: test
2931
body:
3032
- '{"index": {}}'
3133
- '{"title": "Elasticsearch in Action", "suggestions": {"input": "ELK in Action", "contexts": {"format": "ebook"}}}'
3234
- '{"index": {}}'
33-
- '{"title": "Elasticsearch - The Definitive Guide", "suggestions": {"input": ["Elasticsearch in Action"]}}'
34-
35-
---
36-
"Test typed keys parameter for suggesters":
35+
- '{"title": "Elasticsearch - The Definitive Guide", "suggestions": {"input": ["Elasticsearch in Action"], "contexts": {"format": "ebook"}}}'
3736

3837
- do:
3938
search:
@@ -46,10 +45,6 @@ setup:
4645
term_suggester:
4746
term:
4847
field: title
49-
completion_suggester:
50-
prefix: "Elastic"
51-
completion:
52-
field: suggestions
5348
context_suggester:
5449
prefix: "Elastic"
5550
completion:
@@ -61,6 +56,5 @@ setup:
6156
field: title
6257

6358
- is_true: suggest.term#term_suggester
64-
- is_true: suggest.completion#completion_suggester
6559
- is_true: suggest.completion#context_suggester
6660
- is_true: suggest.phrase#phrase_suggester

server/src/main/java/org/elasticsearch/index/mapper/CompletionFieldMapper.java

-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@
8383
* for query-time filtering and boosting (see {@link ContextMappings}
8484
*/
8585
public class CompletionFieldMapper extends FieldMapper implements ArrayValueMapperParser {
86-
8786
public static final String CONTENT_TYPE = "completion";
8887

8988
public static class Defaults {

server/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
* indexing.
5858
*/
5959
public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSuggestionBuilder> {
60+
6061
private static final XContentType CONTEXT_BYTES_XCONTENT_TYPE = XContentType.JSON;
6162
static final String SUGGESTION_NAME = "completion";
6263
static final ParseField CONTEXTS_FIELD = new ParseField("contexts", "context");

server/src/main/java/org/elasticsearch/search/suggest/completion/context/ContextMappings.java

+16
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.apache.lucene.util.CharsRefBuilder;
2626
import org.elasticsearch.ElasticsearchParseException;
2727
import org.elasticsearch.Version;
28+
import org.elasticsearch.common.logging.DeprecationLogger;
29+
import org.elasticsearch.common.logging.Loggers;
2830
import org.elasticsearch.common.xcontent.ToXContent;
2931
import org.elasticsearch.common.xcontent.XContentBuilder;
3032
import org.elasticsearch.index.mapper.CompletionFieldMapper;
@@ -51,6 +53,10 @@
5153
* for a {@link CompletionFieldMapper}
5254
*/
5355
public class ContextMappings implements ToXContent {
56+
57+
private static final DeprecationLogger DEPRECATION_LOGGER =
58+
new DeprecationLogger(Loggers.getLogger(ContextMappings.class));
59+
5460
private final List<ContextMapping> contextMappings;
5561
private final Map<String, ContextMapping> contextNameMap;
5662

@@ -143,6 +149,10 @@ protected Iterable<CharSequence> contexts() {
143149
scratch.setLength(1);
144150
}
145151
}
152+
if (typedContexts.isEmpty()) {
153+
DEPRECATION_LOGGER.deprecated("The ability to index a suggestion with no context on a context enabled completion field" +
154+
" is deprecated and will be removed in the next major release.");
155+
}
146156
return typedContexts;
147157
}
148158
}
@@ -156,6 +166,7 @@ protected Iterable<CharSequence> contexts() {
156166
*/
157167
public ContextQuery toContextQuery(CompletionQuery query, Map<String, List<ContextMapping.InternalQueryContext>> queryContexts) {
158168
ContextQuery typedContextQuery = new ContextQuery(query);
169+
boolean hasContext = false;
159170
if (queryContexts.isEmpty() == false) {
160171
CharsRefBuilder scratch = new CharsRefBuilder();
161172
scratch.grow(1);
@@ -169,10 +180,15 @@ public ContextQuery toContextQuery(CompletionQuery query, Map<String, List<Conte
169180
scratch.append(context.context);
170181
typedContextQuery.addContext(scratch.toCharsRef(), context.boost, !context.isPrefix);
171182
scratch.setLength(1);
183+
hasContext = true;
172184
}
173185
}
174186
}
175187
}
188+
if (hasContext == false) {
189+
DEPRECATION_LOGGER.deprecated("The ability to query with no context on a context enabled completion field is deprecated " +
190+
"and will be removed in the next major release.");
191+
}
176192
return typedContextQuery;
177193
}
178194

0 commit comments

Comments
 (0)