Skip to content
This repository has been archived by the owner on Jun 1, 2021. It is now read-only.

Commit

Permalink
Merge branch 'develop' into vind-v3.1.x
Browse files Browse the repository at this point in the history
  • Loading branch information
Alfonso Noriega Meneses committed May 11, 2021
2 parents 75a83d6 + 5e5231f commit b10b0a2
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 39 deletions.
12 changes: 12 additions & 0 deletions api/src/main/java/com/rbmhtechnology/vind/api/query/sort/Sort.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ public static NumberOfMatchingTermsSort numberOfMatchingTermsSort(FieldDescripto
return new NumberOfMatchingTermsSort(descriptor);
}

/**
* Static method to instantiate a {@link Sort.SpecialSort.NumberOfMatchingTermsSort} sorting object,
* which sorts each field from the query for the number of matching terms.
* @return {@link Sort.SpecialSort.NumberOfMatchingTermsSort} sort query object.
*/
public static NumberOfMatchingTermsSort numberOfMatchingTermsSort() {
return new NumberOfMatchingTermsSort();
}

/**
* Static method to instantiate a {@link com.rbmhtechnology.vind.api.query.distance.Distance} object.
* Be sure that geoDistance is set in search!
Expand Down Expand Up @@ -228,6 +237,9 @@ protected NumberOfMatchingTermsSort(FieldDescriptor descriptor) {
this.descriptor = descriptor;
}

protected NumberOfMatchingTermsSort() {
}

/**
* Gets the {@link FieldDescriptor}.
* @return {@link FieldDescriptor}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public StringSuggestionSearch fulltextTerm(final FulltextTerm fulltextTerm) {
public String getSearchContext() {
return this.searchContext;
}

/**
* Sets a basic {@link com.rbmhtechnology.vind.api.query.filter.Filter.TermFilter} for the suggestion search query.
* @param field String name of the field to filter in.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ private static QueryBuilder filterMapper(Filter filter, DocumentFactory factory,

case "TermFilter":
final Filter.TermFilter termFilter = (Filter.TermFilter) filter;
final Optional<String> termFilterFieldName =
final Optional<String> termFilterFieldName =
FieldUtil.getFieldName(factory.getField(termFilter.getField()), useCase, context, indexFootPrint);
return termFilterFieldName.map(s -> QueryBuilders.termQuery(s, termFilter.getTerm())).orElse(null);
case "TermsQueryFilter":
Expand Down Expand Up @@ -1166,7 +1166,8 @@ public static SearchSourceBuilder buildExperimentalSuggestionQuery(
return searchSource;
}

public static SearchSourceBuilder buildSuggestionQuery(ExecutableSuggestionSearch search, DocumentFactory factory,
public static SearchSourceBuilder buildSuggestionQuery(ExecutableSuggestionSearch search,
DocumentFactory factory,
List<String> indexFootPrint) {

final String searchContext = search.getSearchContext();
Expand Down Expand Up @@ -1196,7 +1197,7 @@ public static SearchSourceBuilder buildSuggestionQuery(ExecutableSuggestionSearc
)
.map(aggregation ->
search.getSort() != null && NUMBER_OF_MATCHING_TERMS_SORT.equals(search.getSort().getType())
? addSubAggregation(aggregation, search, searchContext, indexFootPrint)
? addSubAggregation(aggregation, search, aggregation.field())
: aggregation
)
.forEach(searchSource::aggregation);
Expand All @@ -1220,10 +1221,9 @@ public static SearchSourceBuilder buildSuggestionQuery(ExecutableSuggestionSearc

private static AggregationBuilder addSubAggregation(TermsAggregationBuilder aggregation,
ExecutableSuggestionSearch search,
String searchContext,
List<String> indexFootPrint) {
String fieldName) {
return aggregation
.subAggregation(SortUtils.buildSuggestionSort(RELEVANCE, search.getSort(), searchContext, indexFootPrint, search.getInput()))
.subAggregation(SortUtils.buildSuggestionSort(RELEVANCE, search.getSort(), search.getInput(), fieldName))
.order(BucketOrder.aggregation(RELEVANCE, false));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,11 @@ protected static AggregationBuilder buildFacetSort(String name, Sort sort, Strin

protected static AggregationBuilder buildSuggestionSort(String name,
Sort sort,
String searchContext,
List<String> indexFootPrint,
String input) {
String input,
String fieldName) {
switch (sort.getType()) {
case NUMBER_OF_MATCHING_TERMS_SORT:
return setNumberOfMatchingTermsSort(
name,
(Sort.SpecialSort.NumberOfMatchingTermsSort) sort,
searchContext,
indexFootPrint,
input);
return setNumberOfMatchingTermsSort(name, input, fieldName);
default:
throw new SearchServerException(String
.format("Unable to parse Vind sort '%s' to ElasticSearch sorting: sort type not supported.",
Expand All @@ -173,19 +167,10 @@ protected static AggregationBuilder buildSuggestionSort(String name,
}

private static MaxAggregationBuilder setNumberOfMatchingTermsSort(String name,
Sort.SpecialSort.NumberOfMatchingTermsSort sort,
String searchContext,
List<String> indexFootPrint,
String input) {
final FieldDescriptor descriptor = sort.getDescriptor();
final String matchingField = Optional.ofNullable(descriptor)
.filter(FieldDescriptor::isSort)
.map(field -> FieldUtil.getFieldName(descriptor, FieldDescriptor.UseCase.Sort, searchContext, indexFootPrint)
.orElseThrow(() ->
new SearchServerException("The field '" + descriptor.getName() + "' is not set for context ["+ searchContext +"]")))
.orElse(sort.getField());
String input,
String fieldName) {
final Map<String, Object> parameters = new HashMap<>();
parameters.put("field",matchingField);
parameters.put("field",fieldName);
parameters.put("input", Arrays.asList(input.split(" ")));
final Script painlessMatchingSort = new Script(
ScriptType.INLINE,
Expand Down
67 changes: 67 additions & 0 deletions test/src/test/java/com/rbmhtechnology/vind/test/ServerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import static com.rbmhtechnology.vind.api.query.filter.Filter.or;
import static com.rbmhtechnology.vind.api.query.sort.Sort.Direction;
import static com.rbmhtechnology.vind.api.query.sort.Sort.SpecialSort.distance;
import static com.rbmhtechnology.vind.api.query.sort.Sort.SpecialSort.numberOfMatchingTermsSort;
import static com.rbmhtechnology.vind.api.query.sort.Sort.SpecialSort.score;
import static com.rbmhtechnology.vind.api.query.sort.Sort.SpecialSort.scoredDate;
import static com.rbmhtechnology.vind.api.query.sort.Sort.asc;
Expand Down Expand Up @@ -3912,4 +3913,70 @@ public void testEscapingSpecialCharacters() {

assertEquals(1, result.getResults().size());
}

@Test
@RunWithBackend({Elastic, Solr})
public void testComplexContextSortedSuggestion() {


final MultiValuedComplexField.TextComplexField<Taxonomy, String, String> textMulti =
new ComplexFieldDescriptorBuilder<Taxonomy,String,String>()
.setFullText(true, tx -> Collections.singletonList(tx.getLabel()))
.setSuggest(true, tx -> Collections.singletonList(tx.getLabel()))
.setStored(true, Taxonomy::getLabel)
.buildMultivaluedTextComplexField("textMulti", Taxonomy.class,String.class,String.class);

final NumericFieldDescriptor<Integer> numMulti = new FieldDescriptorBuilder()
.buildMultivaluedNumericField("numMulti", Integer.class);

final Function<Collection<ZonedDateTime>, ZonedDateTime> dateSortFunction = txs -> txs.stream().max(Comparator.<ZonedDateTime>naturalOrder()).get();
final DateFieldDescriptor dateMulti = new FieldDescriptorBuilder()
.buildSortableMultivaluedDateField("dateMulti", dateSortFunction);

final SingleValuedComplexField.UtilDateComplexField<Taxonomy,Date,Date> dateSingle = new ComplexFieldDescriptorBuilder<Taxonomy,Date,Date>()
.setStored(true, tx -> tx.getUtilDate())
.buildUtilDateComplexField("singleDate", Taxonomy.class, Date.class, Date.class);

final MultiValuedComplexField.DateComplexField<Taxonomy,ZonedDateTime,ZonedDateTime> dateComplexMulti = new ComplexFieldDescriptorBuilder<Taxonomy,ZonedDateTime,ZonedDateTime>()
.setStored(true, tx -> tx.getDate())
.buildMultivaluedDateComplexField("dateComplexMulti", Taxonomy.class, ZonedDateTime.class, ZonedDateTime.class);

final DocumentFactory assets = new DocumentFactoryBuilder("asset")
.addField(textMulti)
.addField(numMulti)
.addField(dateMulti)
.addField(dateSingle)
.addField(dateComplexMulti)
.build();

final Document doc1 = assets.createDoc("1")
.setContextualizedValue(textMulti, "en", new Taxonomy("today", 2, "Servus Nachrichten 19:20 -> Season 4 -> Episode 20 - January 20", ZonedDateTime.now()))
.setValues(numMulti,6,7,8)
.setValue(dateSingle, new Taxonomy("today", 2, "todays date", ZonedDateTime.now()))
.setValues(dateComplexMulti, new Taxonomy("today", 2, "todays date", ZonedDateTime.now()), new Taxonomy("today", 2, "todays date", ZonedDateTime.now().minusDays(1)))
.setValues(dateMulti, ZonedDateTime.now().minusMonths(3));

final Document doc2 = assets.createDoc("2")
.setContextualizedValue(textMulti, "en", new Taxonomy("today", 2, "English", ZonedDateTime.now()))
.setValues(numMulti, 1, 2, 3)
.setValue(dateSingle, new Taxonomy("today", 1, "todays date", ZonedDateTime.now().plusDays(1)))
.setValues(dateComplexMulti, new Taxonomy("today", 2, "todays date", ZonedDateTime.now().plusDays(2)), new Taxonomy("today", 2, "todays date", ZonedDateTime.now().minusDays(1)))
.setValues(dateMulti, ZonedDateTime.now().plusMonths(1));


final SearchServer server = testBackend.getSearchServer();

server.index(doc1);
server.index(doc2);
server.commit();

//test empty filter in single valued field
DescriptorSuggestionSearch suggestion = Search.suggest("e nach")
.context("en")
.addField(textMulti)
.setSort(desc(numberOfMatchingTermsSort()));
final SuggestionResult suggestionResult = server.execute( suggestion, assets);
assertEquals( 2, suggestionResult.size());
assertEquals( "Servus Nachrichten 19:20 -> Season 4 -> Episode 20 - January 20", suggestionResult.get(textMulti).getValues().get(0).getValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public void before() {

@Test
@RunWithBackend(Solr)
public void childrenSuggestionTest(){
public void childrenSuggestionTest() {
SuggestionResult suggestionSearch = server.execute(Search.suggest("gree").fields(child_value), parent, child);
assertEquals(1, suggestionSearch.get(child_value).getValues().size());
assertEquals("green", suggestionSearch.get(child_value).getValues().get(0).getValue());
Expand All @@ -135,7 +135,7 @@ public void childrenSuggestionTest(){
assertEquals("black", suggestionSearch.get(shared_value).getValues().get(0).getValue());
assertEquals(3, suggestionSearch.get(shared_value).getValues().get(0).getCount());

suggestionSearch = server.execute(Search.suggest("bl").fields(shared_value,parent_value), parent, child);
suggestionSearch = server.execute(Search.suggest("bl").fields(shared_value, parent_value), parent, child);
assertEquals(1, suggestionSearch.get(shared_value).getValues().size());
assertEquals("black", suggestionSearch.get(shared_value).getValues().get(0).getValue());
assertEquals(3, suggestionSearch.get(shared_value).getValues().get(0).getCount());
Expand All @@ -144,23 +144,23 @@ public void childrenSuggestionTest(){
assertEquals(1, suggestionSearch.get(parent_value).getValues().get(0).getCount());

suggestionSearch = server.execute(Search.suggest("bl")
.fields(shared_value,parent_value)
.filter(Filter.eq(parent_value,"orange")), parent, child);
.fields(shared_value, parent_value)
.filter(Filter.eq(parent_value, "orange")), parent, child);
assertEquals(1, suggestionSearch.get(shared_value).getValues().size());
assertEquals("black", suggestionSearch.get(shared_value).getValues().get(0).getValue());
assertEquals(2, suggestionSearch.get(shared_value).getValues().get(0).getCount());

suggestionSearch = server.execute(Search.suggest("bl")
.fields(shared_value,parent_value,child_value)
.filter(Filter.eq(child_value,"blue")), parent, child);
.fields(shared_value, parent_value, child_value)
.filter(Filter.eq(child_value, "blue")), parent, child);
assertEquals(1, suggestionSearch.get(parent_value).getValues().size());
assertEquals(1, suggestionSearch.get(child_value).getValues().size());
assertEquals("blue", suggestionSearch.get(child_value).getValues().get(0).getValue());
assertEquals(1, suggestionSearch.get(shared_value).getValues().size());

suggestionSearch = server.execute(Search.suggest("bl")
.fields(shared_value,parent_value,child_value)
.filter(Filter.eq(shared_value,"yellow")), parent, child);
.fields(shared_value, parent_value, child_value)
.filter(Filter.eq(shared_value, "yellow")), parent, child);
assertEquals(1, suggestionSearch.get(parent_value).getValues().size());
assertEquals(1, suggestionSearch.get(child_value).getValues().size());
assertEquals("blue", suggestionSearch.get(child_value).getValues().get(0).getValue());
Expand All @@ -171,10 +171,10 @@ public void childrenSuggestionTest(){
@RunWithBackend({Solr, Elastic})
public void testSpecialCharacters() {
server.index(
parent.createDoc("P_SPEC_CHAR").setValue(parent_value, "León"));
parent.createDoc("P_SPEC_CHAR").setValue(parent_value, "León"));
server.commit();

SuggestionResult result = server.execute(Search.suggest("2015León, Mexico").fields(parent_value),parent);
SuggestionResult result = server.execute(Search.suggest("2015León, Mexico").fields(parent_value), parent);
assertNotNull(result);
assertEquals(1, result.size());

Expand All @@ -185,7 +185,7 @@ public void testSpecialCharacters() {
parent.createDoc("P_SPEC_CHAR").setValue(parent_value, "\"Film"));
server.commit();

result = server.execute(Search.suggest("\"Film").fields(parent_value),parent);
result = server.execute(Search.suggest("\"Film").fields(parent_value), parent);
assertNotNull(result);
assertEquals(1, result.size());

Expand Down Expand Up @@ -239,7 +239,7 @@ public void testColonSearch() {
parent.createDoc("P_SPEC_CHAR").setValue(parent_value, "Servus Nachrichten 19:20 -> Season 4 -> Episode 20 - January 20"));
server.commit();

SuggestionResult result = server.execute(Search.suggest("Servus Nachrichten 19:20 Season 4 Episode 20").fields(parent_value),parent);
SuggestionResult result = server.execute(Search.suggest("Servus Nachrichten 19:20 Season 4 Episode 20").fields(parent_value), parent);
assertNotNull(result);
assertEquals(1, result.size());

Expand Down Expand Up @@ -286,4 +286,30 @@ public void testSuggestionSort() {
Assert.assertEquals(3, suggestionResult.size());
Assert.assertEquals("Salzburg City", suggestionResult.get(multi_value).getValues().get(0).getValue());
}

@Test
@RunWithBackend({Elastic})
public void testSuggestionSortWithMultipleFields() {
server.index(
parent.createDoc("multi1").setValue(parent_value, "Lindsey Vonn"),
parent.createDoc("multi2").setValue(parent_value, "New Lockdown"),
parent.createDoc("multi3").setValue(parent_value, "Lindsay Lohan"),
parent.createDoc("multi4").setValue(parent_value, "New Lockdown")
);
server.commit();

server.index(
parent.createDoc("multi1").setValues(multi_value, "Madrid City", "Spain"),
parent.createDoc("multi2").setValues(multi_value, "Bologna City", "Italy"),
parent.createDoc("multi3").setValues(multi_value, "New York City", "USA")
);
server.commit();

final SuggestionResult suggestionResult = server.execute(Search.suggest("New")
.addField(parent_value)
.addField(multi_value)
.setSort(desc(numberOfMatchingTermsSort())), parent);
Assert.assertEquals("New Lockdown", suggestionResult.get(parent_value).getValues().get(0).getValue());
Assert.assertEquals("New York City", suggestionResult.get(multi_value).getValues().get(0).getValue());
}
}

0 comments on commit b10b0a2

Please sign in to comment.