From 17f83f33bbcd81f883bf97da7d65f87a006a9df9 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Tue, 26 Mar 2013 17:44:34 +0100 Subject: [PATCH] Terminate early when no terms left in the suggest string. Closes #2817 --- .../suggest/phrase/CandidateScorer.java | 3 +++ .../search/suggest/phrase/Correction.java | 1 + .../phrase/NoisyChannelSpellChecker.java | 4 ++++ .../search/suggest/SuggestSearchTests.java | 23 +++++++++++++++++++ 4 files changed, 31 insertions(+) diff --git a/src/main/java/org/elasticsearch/search/suggest/phrase/CandidateScorer.java b/src/main/java/org/elasticsearch/search/suggest/phrase/CandidateScorer.java index 69c34be42d6..e8eacf6ddc9 100644 --- a/src/main/java/org/elasticsearch/search/suggest/phrase/CandidateScorer.java +++ b/src/main/java/org/elasticsearch/search/suggest/phrase/CandidateScorer.java @@ -36,6 +36,9 @@ final class CandidateScorer { public Correction[] findBestCandiates(CandidateSet[] sets, float errorFraction, double cutoffScore) throws IOException { + if (sets.length == 0) { + return Correction.EMPTY; + } PriorityQueue corrections = new PriorityQueue(maxNumCorrections) { @Override protected boolean lessThan(Correction a, Correction b) { diff --git a/src/main/java/org/elasticsearch/search/suggest/phrase/Correction.java b/src/main/java/org/elasticsearch/search/suggest/phrase/Correction.java index 66c0ce65039..cde05a08a0a 100644 --- a/src/main/java/org/elasticsearch/search/suggest/phrase/Correction.java +++ b/src/main/java/org/elasticsearch/search/suggest/phrase/Correction.java @@ -26,6 +26,7 @@ import org.elasticsearch.search.suggest.phrase.DirectCandidateGenerator.Candidat //TODO public for tests public final class Correction { + public static final Correction[] EMPTY = new Correction[0]; public double score; public final Candidate[] candidates; diff --git a/src/main/java/org/elasticsearch/search/suggest/phrase/NoisyChannelSpellChecker.java b/src/main/java/org/elasticsearch/search/suggest/phrase/NoisyChannelSpellChecker.java index dc0419285fa..21a28ae770c 100644 --- a/src/main/java/org/elasticsearch/search/suggest/phrase/NoisyChannelSpellChecker.java +++ b/src/main/java/org/elasticsearch/search/suggest/phrase/NoisyChannelSpellChecker.java @@ -104,6 +104,10 @@ public final class NoisyChannelSpellChecker { } }); + if (candidateSetsList.isEmpty()) { + return Correction.EMPTY; + } + for (CandidateSet candidateSet : candidateSetsList) { generator.drawCandidates(candidateSet); } diff --git a/src/test/java/org/elasticsearch/test/integration/search/suggest/SuggestSearchTests.java b/src/test/java/org/elasticsearch/test/integration/search/suggest/SuggestSearchTests.java index f397326ae19..b65d4bb569c 100644 --- a/src/test/java/org/elasticsearch/test/integration/search/suggest/SuggestSearchTests.java +++ b/src/test/java/org/elasticsearch/test/integration/search/suggest/SuggestSearchTests.java @@ -405,6 +405,29 @@ public class SuggestSearchTests extends AbstractNodesTests { // assertThat(search.suggest().suggestions().get(3).getSuggestedWords().get("prefix_abcd").get(4).getTerm(), equalTo("prefix_accd")); } + @Test // see #2817 + public void testStopwordsOnlyPhraseSuggest() throws ElasticSearchException, IOException { + client.admin().indices().prepareDelete().execute().actionGet(); + Builder builder = ImmutableSettings.builder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0); + client.admin().indices().prepareCreate("test").setSettings(builder.build()).execute().actionGet(); + client.admin().cluster().prepareHealth("test").setWaitForGreenStatus().execute().actionGet(); + client.prepareIndex("test", "type1") + .setSource(XContentFactory.jsonBuilder().startObject().field("body", "this is a test").endObject()).execute().actionGet(); + client.admin().indices().prepareRefresh().execute().actionGet(); + + Suggest searchSuggest = searchSuggest( + client, + "a an the", + phraseSuggestion("simple_phrase").field("body").gramSize(1) + .addCandidateGenerator(PhraseSuggestionBuilder.candidateGenerator("body").minWordLength(1).suggestMode("always")) + .size(1)); + assertThat(searchSuggest, notNullValue()); + assertThat(searchSuggest.size(), equalTo(1)); + assertThat(searchSuggest.getSuggestion("simple_phrase").getName(), equalTo("simple_phrase")); + assertThat(searchSuggest.getSuggestion("simple_phrase").getEntries().size(), equalTo(1)); + assertThat(searchSuggest.getSuggestion("simple_phrase").getEntries().get(0).getOptions().size(), equalTo(0)); + } + @Test public void testMarvelHerosPhraseSuggest() throws ElasticSearchException, IOException {