diff --git a/api/src/main/java/com/rbmhtechnology/vind/api/query/FulltextSearch.java b/api/src/main/java/com/rbmhtechnology/vind/api/query/FulltextSearch.java index a177d0c2..15d40060 100644 --- a/api/src/main/java/com/rbmhtechnology/vind/api/query/FulltextSearch.java +++ b/api/src/main/java/com/rbmhtechnology/vind/api/query/FulltextSearch.java @@ -30,7 +30,6 @@ */ public class FulltextSearch { - private String searchString = null; private Filter filter = null; private List sorting = new ArrayList<>(); private int facetMinCount = SearchConfiguration.get(SearchConfiguration.SEARCH_RESULT_FACET_INCLUDE_EMPTY, false)? 0 : 1; @@ -43,17 +42,16 @@ public class FulltextSearch { private DocumentFactory childrenFactory = null; private String timeZone = null; private Distance geoDistance = null; - private String minimumShouldMatch = "1"; private String searchContext = null; private boolean strict = true; private boolean spellcheck = false; private boolean smartParsing = false; + private FulltextTerm fulltextSearchTerm = new FulltextTerm("*", "1"); /** * Creates a new basic full text search query object. */ FulltextSearch() { - this.searchString = "*"; this.resultSet = new Page(1, SearchConfiguration.get(SearchConfiguration.SEARCH_RESULT_PAGESIZE,10)); } @@ -64,7 +62,7 @@ public class FulltextSearch { public FulltextSearch copy() { final FulltextSearch copy = new FulltextSearch(); - copy.searchString = new String(this.searchString); + copy.fulltextSearchTerm = fulltextSearchTerm.copy(); copy.resultSet = resultSet.copy(); if (Objects.nonNull(this.getFilter())) { copy.filter = this.getFilter().clone(); @@ -84,7 +82,7 @@ public FulltextSearch copy() { * @return This {@link FulltextSearch} instance with the new text query. */ public FulltextSearch text(String fullText) { - this.searchString = fullText; + this.fulltextSearchTerm = new FulltextTerm(fullText, this.fulltextSearchTerm.getMinimumMatch()); return this; } @@ -500,7 +498,7 @@ public FulltextSearch geoDistance(MultiValueFieldDescriptor.LocationFieldDescrip * @return String containing the query target. */ public String getSearchString() { - return searchString; + return fulltextSearchTerm.getFulltextSearchTerm(); } /** @@ -508,7 +506,7 @@ public String getSearchString() { * @return String containing the query target. */ public String getEscapedSearchString() { - return StringEscapeUtils.escapeJava(searchString); + return StringEscapeUtils.escapeJava(fulltextSearchTerm.getFulltextSearchTerm()); } /** @@ -638,11 +636,11 @@ public FulltextSearch setStrict(boolean strict) { } public String getMinimumShouldMatch() { - return minimumShouldMatch; + return fulltextSearchTerm.getMinimumMatch(); } public FulltextSearch setMinimumShouldMatch(String minimumShouldMatch) { - this.minimumShouldMatch = minimumShouldMatch; + this.fulltextSearchTerm = new FulltextTerm(fulltextSearchTerm.getFulltextSearchTerm(), minimumShouldMatch); return this; } @@ -706,7 +704,7 @@ public String toString(){ "}"; return String.format(searchString, - this.searchString, + this.fulltextSearchTerm.getFulltextSearchTerm(), this.filter, this.timeZone, CollectionUtils.isNotEmpty(this.sorting) ? "[" + this.sorting.stream().map(f -> f.toString()).collect(Collectors.joining(", ")) +"]": "[]", @@ -750,6 +748,14 @@ public FulltextSearch cursor(String searchAfter, long aliveMinutes) { return this; } + public FulltextTerm getFulltextSearchTerm() { + return this.fulltextSearchTerm; + } + + public void setFulltextSearchTerm(FulltextTerm fulltextSearchTerm) { + this.fulltextSearchTerm = fulltextSearchTerm; + } + public enum Operators { AND, OR } diff --git a/api/src/main/java/com/rbmhtechnology/vind/api/query/FulltextTerm.java b/api/src/main/java/com/rbmhtechnology/vind/api/query/FulltextTerm.java new file mode 100644 index 00000000..95f1fccb --- /dev/null +++ b/api/src/main/java/com/rbmhtechnology/vind/api/query/FulltextTerm.java @@ -0,0 +1,23 @@ +package com.rbmhtechnology.vind.api.query; + +public class FulltextTerm { + private final String fulltextSearchTerm; + private final String minimumMatch; + + public FulltextTerm(String fulltextSearchTerm, String minimumMatch) { + this.fulltextSearchTerm = fulltextSearchTerm; + this.minimumMatch = minimumMatch; + } + + public String getFulltextSearchTerm() { + return fulltextSearchTerm; + } + + public String getMinimumMatch() { + return minimumMatch; + } + + public FulltextTerm copy() { + return new FulltextTerm(getFulltextSearchTerm(), getMinimumMatch()); + } +} diff --git a/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/DescriptorSuggestionSearch.java b/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/DescriptorSuggestionSearch.java index d58de0f8..73d6a947 100644 --- a/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/DescriptorSuggestionSearch.java +++ b/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/DescriptorSuggestionSearch.java @@ -1,13 +1,18 @@ package com.rbmhtechnology.vind.api.query.suggestion; +import com.rbmhtechnology.vind.api.query.FulltextSearch; +import com.rbmhtechnology.vind.api.query.FulltextTerm; import com.rbmhtechnology.vind.api.query.filter.Filter; import com.rbmhtechnology.vind.model.FieldDescriptor; import java.util.Arrays; import java.util.HashSet; import java.util.Objects; +import java.util.Optional; import java.util.Set; +import static java.util.Optional.empty; + /** * Class to configure suggestions based on field descriptors. * @@ -21,6 +26,8 @@ public class DescriptorSuggestionSearch implements ExecutableSuggestionSearch { private Filter filter = null; private Set suggestionFields = new HashSet<>(); private String searchContext = null; + private Optional fulltextTerm = empty(); + /** * Creates a new instance of {@link DescriptorSuggestionSearch}. * @param input String text to find suggestion for. @@ -28,14 +35,14 @@ public class DescriptorSuggestionSearch implements ExecutableSuggestionSearch { * @param field {@link FieldDescriptor} fields where to find the suggestions. */ protected DescriptorSuggestionSearch(String input, int limit, Filter filter, FieldDescriptor ... field) { - Objects.requireNonNull(field); - this.input = input; - this.limit = limit; - this.filter = filter; - suggestionFields.addAll(Arrays.asList(field)); + Objects.requireNonNull(field); + this.input = input; + this.limit = limit; + this.filter = filter; + suggestionFields.addAll(Arrays.asList(field)); } - /** + /** * Set the text to find suggestions for. * @param input String text to find suggestion for. * @return {@link DescriptorSuggestionSearch} with the new text. @@ -162,4 +169,13 @@ public boolean hasFilter() { public boolean isStringSuggestion() { return false; } + + public Optional getFulltextTerm() { + return fulltextTerm; + } + + public DescriptorSuggestionSearch fulltextTerm(final FulltextTerm fulltextTerm) { + this.fulltextTerm = Optional.ofNullable(fulltextTerm); + return this; + } } diff --git a/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/ExecutableSuggestionSearch.java b/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/ExecutableSuggestionSearch.java index 02d884ae..a1f50fd1 100644 --- a/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/ExecutableSuggestionSearch.java +++ b/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/ExecutableSuggestionSearch.java @@ -1,7 +1,10 @@ package com.rbmhtechnology.vind.api.query.suggestion; +import com.rbmhtechnology.vind.api.query.FulltextTerm; import com.rbmhtechnology.vind.api.query.filter.Filter; +import java.util.Optional; + /** * @author Thomas Kurz (tkurz@apache.org) * @since 07.07.16. @@ -23,6 +26,10 @@ public interface ExecutableSuggestionSearch { public ExecutableSuggestionSearch context(String context); + public Optional getFulltextTerm(); + + public ExecutableSuggestionSearch fulltextTerm(FulltextTerm fulltextTerm); + public int getLimit(); String getSearchContext(); diff --git a/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/StringSuggestionSearch.java b/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/StringSuggestionSearch.java index 5b3a084a..68f9b6c6 100644 --- a/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/StringSuggestionSearch.java +++ b/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/StringSuggestionSearch.java @@ -1,12 +1,16 @@ package com.rbmhtechnology.vind.api.query.suggestion; +import com.rbmhtechnology.vind.api.query.FulltextTerm; import com.rbmhtechnology.vind.api.query.filter.Filter; import java.util.Arrays; import java.util.HashSet; import java.util.Objects; +import java.util.Optional; import java.util.Set; +import static java.util.Optional.empty; + /** * Class to configure suggestions based on field String names. * @@ -20,6 +24,7 @@ public class StringSuggestionSearch implements ExecutableSuggestionSearch { private Filter filter = null; private Set suggestionFields = new HashSet<>(); private String searchContext = null; + private Optional fulltextTerm = empty(); /** * Creates a new instance of {@link StringSuggestionSearch}. @@ -61,6 +66,17 @@ public StringSuggestionSearch context(String context) { return this; } + @Override + public Optional getFulltextTerm() { + return fulltextTerm; + } + + @Override + public StringSuggestionSearch fulltextTerm(final FulltextTerm fulltextTerm) { + this.fulltextTerm = Optional.ofNullable(fulltextTerm); + return this; + } + @Override public String getSearchContext() { return this.searchContext; diff --git a/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/SuggestionSearch.java b/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/SuggestionSearch.java index 0dee1d68..d39e62ed 100644 --- a/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/SuggestionSearch.java +++ b/api/src/main/java/com/rbmhtechnology/vind/api/query/suggestion/SuggestionSearch.java @@ -1,13 +1,18 @@ package com.rbmhtechnology.vind.api.query.suggestion; +import com.rbmhtechnology.vind.api.query.FulltextTerm; import com.rbmhtechnology.vind.api.query.filter.Filter; +import com.rbmhtechnology.vind.model.DocumentFactoryBuilder; import com.rbmhtechnology.vind.model.FieldDescriptor; import java.util.HashSet; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import static java.util.Optional.empty; + /** * Class to prepare suggestion queries. */ @@ -19,6 +24,7 @@ public class SuggestionSearch { private Set suggestionFields = new HashSet<>(); private Set suggestionStringFields = new HashSet<>(); private String searchContext = null; + private Optional fulltextTerm = empty(); /** * Creates a new instance of {@link SuggestionSearch}. @@ -42,6 +48,7 @@ public SuggestionSearch copy() { copy.suggestionFields = this.suggestionFields; copy.suggestionStringFields = this.suggestionStringFields; copy.searchContext = this.searchContext; + copy.fulltextTerm = this.fulltextTerm; return copy; } @@ -123,7 +130,7 @@ public Set getSuggestionStringFields() { */ //FIXME: this supports also: fields() public StringSuggestionSearch fields(String... fields) { - return new StringSuggestionSearch(input,limit,filter,fields).context(this.searchContext); + return new StringSuggestionSearch(input,limit,filter,fields).context(this.searchContext).fulltextTerm(fulltextTerm.orElse(null)); } /** @@ -132,7 +139,7 @@ public StringSuggestionSearch fields(String... fields) { * @return {@link DescriptorSuggestionSearch} with the added field. */ public DescriptorSuggestionSearch addField(FieldDescriptor field) { - return new DescriptorSuggestionSearch(input,limit,filter,field).context(this.searchContext); + return new DescriptorSuggestionSearch(input,limit,filter,field).context(this.searchContext).fulltextTerm(fulltextTerm.orElse(null)); } /** * Adds the fields to search for suggestions in. @@ -141,7 +148,7 @@ public DescriptorSuggestionSearch addField(FieldDescriptor field) { */ //FIXME: this supports also: fields() public DescriptorSuggestionSearch fields(FieldDescriptor... fields) { - return new DescriptorSuggestionSearch(input,limit,filter,fields).context(this.searchContext); + return new DescriptorSuggestionSearch(input,limit,filter,fields).context(this.searchContext).fulltextTerm(fulltextTerm.orElse(null)); } /** @@ -177,4 +184,18 @@ public String getSearchContext() { return this.searchContext; } + /** + * Get the fulltext term, to base the search on. + * Useful when suggesting within an already existing fulltext search + * + * @return a fulltext term + */ + public Optional getFulltextTerm() { + return fulltextTerm; + } + + public SuggestionSearch fulltextTerm(final FulltextTerm fulltextTerm) { + this.fulltextTerm = Optional.ofNullable(fulltextTerm); + return this; + } } diff --git a/backend/elasticsearch/src/main/java/com/rbmhtechnology/vind/elasticsearch/backend/util/ElasticQueryBuilder.java b/backend/elasticsearch/src/main/java/com/rbmhtechnology/vind/elasticsearch/backend/util/ElasticQueryBuilder.java index e560a315..1eb27275 100644 --- a/backend/elasticsearch/src/main/java/com/rbmhtechnology/vind/elasticsearch/backend/util/ElasticQueryBuilder.java +++ b/backend/elasticsearch/src/main/java/com/rbmhtechnology/vind/elasticsearch/backend/util/ElasticQueryBuilder.java @@ -4,6 +4,7 @@ import com.google.common.collect.Streams; import com.rbmhtechnology.vind.SearchServerException; import com.rbmhtechnology.vind.api.query.FulltextSearch; +import com.rbmhtechnology.vind.api.query.FulltextTerm; import com.rbmhtechnology.vind.api.query.datemath.DateMathExpression; import com.rbmhtechnology.vind.api.query.division.Cursor; import com.rbmhtechnology.vind.api.query.division.Page; @@ -52,7 +53,6 @@ import org.elasticsearch.search.aggregations.metrics.ParsedCardinality; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; -import org.elasticsearch.search.slice.SliceBuilder; import org.elasticsearch.search.suggest.Suggest; import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option; import org.elasticsearch.search.suggest.SuggestBuilder; @@ -153,26 +153,7 @@ public static SearchSourceBuilder buildQuery(FulltextSearch search, DocumentFact searchString = skipColonSearchString; } - String minimumShouldMatch = search.getMinimumShouldMatch(); - if(StringUtils.isNumeric(minimumShouldMatch) && !minimumShouldMatch.startsWith("-")) { - minimumShouldMatch = "0<" + minimumShouldMatch; - } - final QueryStringQueryBuilder fullTextStringQuery = QueryBuilders.queryStringQuery(searchString) - .minimumShouldMatch(minimumShouldMatch); //mm - // Set fulltext fields - factory.getFields().values().stream() - .filter( FieldDescriptor::isFullText) - .map( field -> Pair.of(FieldUtil.getFieldName(field, UseCase.Fulltext, searchContext, indexFootPrint), field.getBoost())) - .filter( pair -> pair.getKey().isPresent()) - .forEach( field -> fullTextStringQuery - .field(field.getKey().get(),field.getValue())); - - if(fullTextStringQuery.fields().isEmpty()) { - fullTextStringQuery.defaultField("full_text"); - } - - final DisMaxQueryBuilder query = QueryBuilders.disMaxQuery() - .add(fullTextStringQuery); + final DisMaxQueryBuilder query = createDisMaxQueryBuilder(new FulltextTerm(searchString, search.getMinimumShouldMatch()), factory, indexFootPrint, searchContext); baseQuery.must(query); searchSource.query(baseQuery); @@ -316,6 +297,29 @@ public static SearchSourceBuilder buildQuery(FulltextSearch search, DocumentFact return searchSource; } + private static DisMaxQueryBuilder createDisMaxQueryBuilder(FulltextTerm fulltextTerm, DocumentFactory factory, List indexFootPrint, String searchContext) { + String minimumShouldMatch = fulltextTerm.getMinimumMatch(); + if(StringUtils.isNumeric(minimumShouldMatch) && !minimumShouldMatch.startsWith("-")) { + minimumShouldMatch = "0<" + minimumShouldMatch; + } + final QueryStringQueryBuilder fullTextStringQuery = QueryBuilders.queryStringQuery(fulltextTerm.getFulltextSearchTerm()) + .minimumShouldMatch(minimumShouldMatch); //mm + // Set fulltext fields + factory.getFields().values().stream() + .filter( FieldDescriptor::isFullText) + .map( field -> Pair.of(FieldUtil.getFieldName(field, UseCase.Fulltext, searchContext, indexFootPrint), field.getBoost())) + .filter( pair -> pair.getKey().isPresent()) + .forEach( field -> fullTextStringQuery + .field(field.getKey().get(),field.getValue())); + + if(fullTextStringQuery.fields().isEmpty()) { + fullTextStringQuery.defaultField("full_text"); + } + + return QueryBuilders.disMaxQuery() + .add(fullTextStringQuery); + } + public static SearchSourceBuilder buildPercolatorQueryReadiness(DocumentFactory factory) { final SearchSourceBuilder searchSource = new SearchSourceBuilder(); @@ -382,14 +386,14 @@ private static QueryBuilder filterMapper(Filter filter, DocumentFactory factory, case "TermsQueryFilter": final Filter.TermsQueryFilter termsQueryFilter = (Filter.TermsQueryFilter) filter; - final Optional termsQueryFilterFieldName = + final Optional termsQueryFilterFieldName = FieldUtil.getFieldName(factory.getField(termsQueryFilter.getField()), useCase,context, indexFootPrint); return termsQueryFilterFieldName.map(s -> QueryBuilders .termsQuery(s, termsQueryFilter.getTerm())).orElse(null); case "PrefixFilter": final Filter.PrefixFilter prefixFilter = (Filter.PrefixFilter) filter; - final Optional prefixQueryFilterFieldName = + final Optional prefixQueryFilterFieldName = FieldUtil.getFieldName(factory.getField(prefixFilter.getField()), useCase,context, indexFootPrint) ; return prefixQueryFilterFieldName.map(s -> QueryBuilders @@ -397,7 +401,7 @@ private static QueryBuilder filterMapper(Filter filter, DocumentFactory factory, case "DescriptorFilter": final Filter.DescriptorFilter descriptorFilter = (Filter.DescriptorFilter) filter; - final Optional descriptorQueryFilterFieldName = + final Optional descriptorQueryFilterFieldName = FieldUtil.getFieldName(descriptorFilter.getDescriptor(), useCase, context, indexFootPrint) ; return descriptorQueryFilterFieldName.map(s -> QueryBuilders @@ -405,7 +409,7 @@ private static QueryBuilder filterMapper(Filter filter, DocumentFactory factory, case "BetweenDatesFilter": final Filter.BetweenDatesFilter betweenDatesFilter = (Filter.BetweenDatesFilter) filter; - final Optional betweenDatesQueryFilterFieldName = + final Optional betweenDatesQueryFilterFieldName = FieldUtil.getFieldName(factory.getField(betweenDatesFilter.getField()), useCase,context, indexFootPrint) ; return betweenDatesQueryFilterFieldName.map(s -> QueryBuilders @@ -416,7 +420,7 @@ private static QueryBuilder filterMapper(Filter filter, DocumentFactory factory, case "BeforeFilter": final Filter.BeforeFilter beforeFilter = (Filter.BeforeFilter) filter; - final Optional beforeQueryFilterFieldName = + final Optional beforeQueryFilterFieldName = FieldUtil.getFieldName(factory.getField(beforeFilter.getField()), useCase,context, indexFootPrint) ; return beforeQueryFilterFieldName.map(s -> QueryBuilders @@ -426,7 +430,7 @@ private static QueryBuilder filterMapper(Filter filter, DocumentFactory factory, case "AfterFilter": final Filter.AfterFilter afterFilter = (Filter.AfterFilter) filter; - final Optional afterQueryFilterFieldName = + final Optional afterQueryFilterFieldName = FieldUtil.getFieldName(factory.getField(afterFilter.getField()), useCase,context, indexFootPrint) ; return afterQueryFilterFieldName.map(s -> QueryBuilders @@ -436,7 +440,7 @@ private static QueryBuilder filterMapper(Filter filter, DocumentFactory factory, case "BetweenNumericFilter": final Filter.BetweenNumericFilter betweenNumericFilter = (Filter.BetweenNumericFilter) filter; - final Optional betweenNumericQueryFilterFieldName = + final Optional betweenNumericQueryFilterFieldName = FieldUtil.getFieldName(factory.getField(betweenNumericFilter.getField()), useCase, context, indexFootPrint); return betweenNumericQueryFilterFieldName.map(s -> QueryBuilders .rangeQuery(betweenNumericQueryFilterFieldName.get()) @@ -445,7 +449,7 @@ private static QueryBuilder filterMapper(Filter filter, DocumentFactory factory, .orElse(null); case "LowerThanFilter": final Filter.LowerThanFilter lowerThanFilter = (Filter.LowerThanFilter) filter; - final Optional lowerThanQueryFilterFieldName = + final Optional lowerThanQueryFilterFieldName = FieldUtil.getFieldName(factory.getField(lowerThanFilter.getField()), useCase, context, indexFootPrint); return lowerThanQueryFilterFieldName.map(s -> QueryBuilders .rangeQuery(lowerThanQueryFilterFieldName.get()) @@ -1198,6 +1202,11 @@ public static SearchSourceBuilder buildSuggestionQuery(ExecutableSuggestionSearc FieldUtil.getSourceFieldName(fieldName.replaceAll("\\.suggestion", ""), searchContext), SuggestBuilders.termSuggestion(fieldName.concat("_experimental")).prefixLength(0))); + search.getFulltextTerm().ifPresent(fulltextTerm -> { + QueryBuilder query = createDisMaxQueryBuilder(fulltextTerm, factory, indexFootPrint, searchContext); + searchSource.query(query); + }); + searchSource.suggest(suggestBuilder); return searchSource; } diff --git a/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrSearchServer.java b/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrSearchServer.java index 687c3ca6..3a695d38 100644 --- a/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrSearchServer.java +++ b/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrSearchServer.java @@ -1035,6 +1035,8 @@ protected SolrQuery buildSolrQuery(ExecutableSuggestionSearch search, DocumentFa query.add(CommonParams.FQ, parentTypeFilter); + search.getFulltextTerm().ifPresent(fulltextTerm -> query.add(CommonParams.FQ, fulltextTerm.getFulltextSearchTerm())); + //filters if(search.hasFilter()) { SolrUtils.Query.buildFilterString(search.getFilter(), assets,childFactory,query, searchContext, false); diff --git a/pom.xml b/pom.xml index 03438741..d76b8bbe 100644 --- a/pom.xml +++ b/pom.xml @@ -580,13 +580,13 @@ elastic - - - solr true + + solr + quick diff --git a/test/src/test/java/com/rbmhtechnology/vind/test/SuggestionSearchIT.java b/test/src/test/java/com/rbmhtechnology/vind/test/SuggestionSearchIT.java index 1d3c1905..af3e6cb2 100644 --- a/test/src/test/java/com/rbmhtechnology/vind/test/SuggestionSearchIT.java +++ b/test/src/test/java/com/rbmhtechnology/vind/test/SuggestionSearchIT.java @@ -4,6 +4,7 @@ package com.rbmhtechnology.vind.test; import com.rbmhtechnology.vind.api.SearchServer; +import com.rbmhtechnology.vind.api.query.FulltextTerm; import com.rbmhtechnology.vind.api.query.Search; import com.rbmhtechnology.vind.api.query.filter.Filter; import com.rbmhtechnology.vind.api.result.SearchResult; @@ -17,6 +18,8 @@ import org.junit.Rule; import org.junit.Test; +import java.util.Optional; + import static com.rbmhtechnology.vind.api.query.filter.Filter.eq; import static com.rbmhtechnology.vind.test.Backend.Elastic; import static com.rbmhtechnology.vind.test.Backend.Solr; @@ -185,6 +188,7 @@ public void testSpecialCharacters() { server.delete(parent.createDoc("P_SPEC_CHAR")); server.commit(); } + @Test @RunWithBackend({Solr, Elastic}) public void testMultiWordSuggestion() { @@ -204,6 +208,26 @@ public void testMultiWordSuggestion() { } + @Test + @RunWithBackend({Solr, Elastic}) + public void testMultiWordSuggestionWithBaseSearchTerm() { + + server.index( + parent.createDoc("multi1").setValue(parent_value, "León city")); + server.index( + parent.createDoc("multi2").setValue(parent_value, "Lerida")); + server.index( + parent.createDoc("multi3").setValue(parent_value, "Oviedo city")); + server.index( + parent.createDoc("multi4").setValue(parent_value, "Oviñana")); + server.commit(); + + SuggestionResult suggestionResult = server.execute(Search.suggest("Ov").fulltextTerm(new FulltextTerm("city", "100%")).addField(parent_value), parent); + + Assert.assertEquals(1, suggestionResult.size()); + assertEquals("Oviedo city", suggestionResult.get(parent_value).getValues().get(0).getValue()); + } + @Test @RunWithBackend({Solr, Elastic}) public void testColonSearch() {