summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorChristoph Büscher <christoph@elastic.co>2017-03-16 21:36:18 +0100
committerGitHub <noreply@github.com>2017-03-16 21:36:18 +0100
commit96a92da682f71f49764affeed5629b32d8f226d3 (patch)
treed6417a1e2ffd0050f8e313db0df3c2e4c9b0a74c /core/src
parent6e9dfb334889258ff9205004ed8a851e1bc67d83 (diff)
CompletionSuggestionContext#toQuery() should also consider text if prefix/regex missing (#23451)
In cases where the user specifies only the `text` option on the top level suggest element (either via REST or the java api), this gets transferred to the `text` property in the SuggestionSearchContext. CompletionSuggestionContext currently requires prefix or regex to be specified, otherwise errors. We should use the global `text` property as a fallback if neither prefix nor regex is provided. Closes to #23340
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java29
-rw-r--r--core/src/test/java/org/elasticsearch/search/suggest/CompletionSuggestSearchIT.java38
2 files changed, 52 insertions, 15 deletions
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java
index a4aeec8cb5..b12b90de10 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java
@@ -19,6 +19,7 @@
package org.elasticsearch.search.suggest.completion;
import org.apache.lucene.search.suggest.document.CompletionQuery;
+import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.mapper.CompletionFieldMapper;
import org.elasticsearch.index.query.QueryShardContext;
@@ -77,15 +78,7 @@ public class CompletionSuggestionContext extends SuggestionSearchContext.Suggest
CompletionFieldMapper.CompletionFieldType fieldType = getFieldType();
final CompletionQuery query;
if (getPrefix() != null) {
- if (fuzzyOptions != null) {
- query = fieldType.fuzzyQuery(getPrefix().utf8ToString(),
- Fuzziness.fromEdits(fuzzyOptions.getEditDistance()),
- fuzzyOptions.getFuzzyPrefixLength(), fuzzyOptions.getFuzzyMinLength(),
- fuzzyOptions.getMaxDeterminizedStates(), fuzzyOptions.isTranspositions(),
- fuzzyOptions.isUnicodeAware());
- } else {
- query = fieldType.prefixQuery(getPrefix());
- }
+ query = createCompletionQuery(getPrefix(), fieldType);
} else if (getRegex() != null) {
if (fuzzyOptions != null) {
throw new IllegalArgumentException("can not use 'fuzzy' options with 'regex");
@@ -95,8 +88,10 @@ public class CompletionSuggestionContext extends SuggestionSearchContext.Suggest
}
query = fieldType.regexpQuery(getRegex(), regexOptions.getFlagsValue(),
regexOptions.getMaxDeterminizedStates());
+ } else if (getText() != null) {
+ query = createCompletionQuery(getText(), fieldType);
} else {
- throw new IllegalArgumentException("'prefix' or 'regex' must be defined");
+ throw new IllegalArgumentException("'prefix/text' or 'regex' must be defined");
}
if (fieldType.hasContextMappings()) {
ContextMappings contextMappings = fieldType.getContextMappings();
@@ -105,4 +100,18 @@ public class CompletionSuggestionContext extends SuggestionSearchContext.Suggest
return query;
}
+ private CompletionQuery createCompletionQuery(BytesRef prefix, CompletionFieldMapper.CompletionFieldType fieldType) {
+ final CompletionQuery query;
+ if (fuzzyOptions != null) {
+ query = fieldType.fuzzyQuery(prefix.utf8ToString(),
+ Fuzziness.fromEdits(fuzzyOptions.getEditDistance()),
+ fuzzyOptions.getFuzzyPrefixLength(), fuzzyOptions.getFuzzyMinLength(),
+ fuzzyOptions.getMaxDeterminizedStates(), fuzzyOptions.isTranspositions(),
+ fuzzyOptions.isUnicodeAware());
+ } else {
+ query = fieldType.prefixQuery(prefix);
+ }
+ return query;
+ }
+
}
diff --git a/core/src/test/java/org/elasticsearch/search/suggest/CompletionSuggestSearchIT.java b/core/src/test/java/org/elasticsearch/search/suggest/CompletionSuggestSearchIT.java
index 07502ff338..5bd2bad31d 100644
--- a/core/src/test/java/org/elasticsearch/search/suggest/CompletionSuggestSearchIT.java
+++ b/core/src/test/java/org/elasticsearch/search/suggest/CompletionSuggestSearchIT.java
@@ -68,12 +68,10 @@ import static org.elasticsearch.common.util.CollectionUtils.iterableAsArrayList;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAllSuccessful;
-import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHit;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasId;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.hasScore;
import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
@@ -116,6 +114,36 @@ public class CompletionSuggestSearchIT extends ESIntegTestCase {
assertSuggestions("foo", prefix, "suggestion10", "suggestion9", "suggestion8", "suggestion7", "suggestion6");
}
+ /**
+ * test that suggestion works if prefix is either provided via {@link CompletionSuggestionBuilder#text(String)} or
+ * {@link SuggestBuilder#setGlobalText(String)}
+ */
+ public void testTextAndGlobalText() throws Exception {
+ final CompletionMappingBuilder mapping = new CompletionMappingBuilder();
+ createIndexAndMapping(mapping);
+ int numDocs = 10;
+ List<IndexRequestBuilder> indexRequestBuilders = new ArrayList<>();
+ for (int i = 1; i <= numDocs; i++) {
+ indexRequestBuilders.add(client().prepareIndex(INDEX, TYPE, "" + i).setSource(jsonBuilder().startObject().startObject(FIELD)
+ .field("input", "suggestion" + i).field("weight", i).endObject().endObject()));
+ }
+ indexRandom(true, indexRequestBuilders);
+ CompletionSuggestionBuilder noText = SuggestBuilders.completionSuggestion(FIELD);
+ SearchResponse searchResponse = client().prepareSearch(INDEX)
+ .suggest(new SuggestBuilder().addSuggestion("foo", noText).setGlobalText("sugg")).execute().actionGet();
+ assertSuggestions(searchResponse, "foo", "suggestion10", "suggestion9", "suggestion8", "suggestion7", "suggestion6");
+
+ CompletionSuggestionBuilder withText = SuggestBuilders.completionSuggestion(FIELD).text("sugg");
+ searchResponse = client().prepareSearch(INDEX)
+ .suggest(new SuggestBuilder().addSuggestion("foo", withText)).execute().actionGet();
+ assertSuggestions(searchResponse, "foo", "suggestion10", "suggestion9", "suggestion8", "suggestion7", "suggestion6");
+
+ // test that suggestion text takes precedence over global text
+ searchResponse = client().prepareSearch(INDEX)
+ .suggest(new SuggestBuilder().addSuggestion("foo", withText).setGlobalText("bogus")).execute().actionGet();
+ assertSuggestions(searchResponse, "foo", "suggestion10", "suggestion9", "suggestion8", "suggestion7", "suggestion6");
+ }
+
public void testRegex() throws Exception {
final CompletionMappingBuilder mapping = new CompletionMappingBuilder();
createIndexAndMapping(mapping);
@@ -217,7 +245,7 @@ public class CompletionSuggestSearchIT extends ESIntegTestCase {
for (CompletionSuggestion.Entry.Option option : options) {
assertThat(option.getText().toString(), equalTo("suggestion" + id));
assertSearchHit(option.getHit(), hasId("" + id));
- assertSearchHit(option.getHit(), hasScore(((float) id)));
+ assertSearchHit(option.getHit(), hasScore((id)));
assertNotNull(option.getHit().getSourceAsMap());
id--;
}
@@ -252,7 +280,7 @@ public class CompletionSuggestSearchIT extends ESIntegTestCase {
for (CompletionSuggestion.Entry.Option option : options) {
assertThat(option.getText().toString(), equalTo("suggestion" + id));
assertSearchHit(option.getHit(), hasId("" + id));
- assertSearchHit(option.getHit(), hasScore(((float) id)));
+ assertSearchHit(option.getHit(), hasScore((id)));
assertNull(option.getHit().getSourceAsMap());
id--;
}
@@ -289,7 +317,7 @@ public class CompletionSuggestSearchIT extends ESIntegTestCase {
for (CompletionSuggestion.Entry.Option option : options) {
assertThat(option.getText().toString(), equalTo("suggestion" + id));
assertSearchHit(option.getHit(), hasId("" + id));
- assertSearchHit(option.getHit(), hasScore(((float) id)));
+ assertSearchHit(option.getHit(), hasScore((id)));
assertNotNull(option.getHit().getSourceAsMap());
Set<String> sourceFields = option.getHit().getSourceAsMap().keySet();
assertThat(sourceFields, contains("a"));