diff --git a/src/main/java/org/codelibs/fess/entity/QueryContext.java b/src/main/java/org/codelibs/fess/entity/QueryContext.java index f15612160..5596eb971 100644 --- a/src/main/java/org/codelibs/fess/entity/QueryContext.java +++ b/src/main/java/org/codelibs/fess/entity/QueryContext.java @@ -43,19 +43,19 @@ public class QueryContext { protected static final String ALLINTITLE_FIELD_PREFIX = "allintitle:"; - private QueryBuilder queryBuilder; + protected QueryBuilder queryBuilder; - private final List> sortBuilderList = new ArrayList<>(); + protected final List> sortBuilderList = new ArrayList<>(); - private String queryString; + protected String queryString; - private Set highlightedQuerySet = null; + protected Set highlightedQuerySet = null; - private Map> fieldLogMap = null; + protected Map> fieldLogMap = null; - private boolean disableRoleQuery = false; + protected boolean disableRoleQuery = false; - private String defaultField = null; + protected String defaultField = null; @SuppressWarnings("unchecked") public QueryContext(final String queryString, final boolean isQuery) { diff --git a/src/main/java/org/codelibs/fess/query/FuzzyQueryCommand.java b/src/main/java/org/codelibs/fess/query/FuzzyQueryCommand.java index 2ff343bf4..00697a8c2 100644 --- a/src/main/java/org/codelibs/fess/query/FuzzyQueryCommand.java +++ b/src/main/java/org/codelibs/fess/query/FuzzyQueryCommand.java @@ -54,23 +54,29 @@ public class FuzzyQueryCommand extends QueryCommand { final FessConfig fessConfig = ComponentUtil.getFessConfig(); final Term term = fuzzyQuery.getTerm(); final String field = getSearchField(context.getDefaultField(), term.field()); - // TODO fuzzy value + if (Constants.DEFAULT_FIELD.equals(field)) { - context.addFieldLog(field, term.text()); + final String text = term.text(); + context.addFieldLog(field, text); + context.addHighlightedQuery(text); return buildDefaultQueryBuilder(fessConfig, context, - (f, b) -> QueryBuilders.fuzzyQuery(f, term.text()).fuzziness(Fuzziness.fromEdits(fuzzyQuery.getMaxEdits())) - .boost(b * boost).maxExpansions(fessConfig.getQueryFuzzyExpansionsAsInteger()) + (f, b) -> QueryBuilders.fuzzyQuery(f, text).fuzziness(Fuzziness.fromEdits(fuzzyQuery.getMaxEdits())).boost(b * boost) + .maxExpansions(fessConfig.getQueryFuzzyExpansionsAsInteger()) .prefixLength(fessConfig.getQueryFuzzyPrefixLengthAsInteger()) .transpositions(Constants.TRUE.equalsIgnoreCase(fessConfig.getQueryFuzzyTranspositions()))); } + if (isSearchField(field)) { - context.addFieldLog(field, term.text()); - return QueryBuilders.fuzzyQuery(field, term.text()).boost(boost).fuzziness(Fuzziness.fromEdits(fuzzyQuery.getMaxEdits())) + final String text = term.text(); + context.addFieldLog(field, text); + context.addHighlightedQuery(text); + return QueryBuilders.fuzzyQuery(field, text).boost(boost).fuzziness(Fuzziness.fromEdits(fuzzyQuery.getMaxEdits())) .maxExpansions(fessConfig.getQueryFuzzyExpansionsAsInteger()) .prefixLength(fessConfig.getQueryFuzzyPrefixLengthAsInteger()) .transpositions(Constants.TRUE.equalsIgnoreCase(fessConfig.getQueryFuzzyTranspositions())); } - final String origQuery = fuzzyQuery.toString(); + + final String origQuery = term.toString(); context.addFieldLog(Constants.DEFAULT_FIELD, origQuery); context.addHighlightedQuery(origQuery); return buildDefaultQueryBuilder(fessConfig, context, diff --git a/src/main/java/org/codelibs/fess/query/PhraseQueryCommand.java b/src/main/java/org/codelibs/fess/query/PhraseQueryCommand.java index 78a84bd62..3c1c40d2b 100644 --- a/src/main/java/org/codelibs/fess/query/PhraseQueryCommand.java +++ b/src/main/java/org/codelibs/fess/query/PhraseQueryCommand.java @@ -22,6 +22,7 @@ import org.apache.logging.log4j.Logger; import org.apache.lucene.index.Term; import org.apache.lucene.search.PhraseQuery; import org.apache.lucene.search.Query; +import org.codelibs.fess.Constants; import org.codelibs.fess.entity.QueryContext; import org.codelibs.fess.exception.InvalidQueryException; import org.codelibs.fess.mylasta.direction.FessConfig; @@ -59,8 +60,20 @@ public class PhraseQueryCommand extends QueryCommand { final String field = terms[0].field(); final String[] texts = stream(terms).get(stream -> stream.map(Term::text).toArray(n -> new String[n])); final String text = String.join(" ", texts); - context.addFieldLog(field, text); - stream(texts).of(stream -> stream.forEach(t -> context.addHighlightedQuery(t))); + + if (Constants.DEFAULT_FIELD.equals(field)) { + context.addFieldLog(field, text); + stream(texts).of(stream -> stream.forEach(t -> context.addHighlightedQuery(t))); + return buildDefaultQueryBuilder(fessConfig, context, (f, b) -> buildMatchPhraseQuery(f, text).boost(b * boost)); + } + + if (isSearchField(field)) { + context.addFieldLog(field, text); + stream(texts).of(stream -> stream.forEach(t -> context.addHighlightedQuery(t))); + return buildMatchPhraseQuery(field, text); + } + + context.addFieldLog(Constants.DEFAULT_FIELD, text); return buildDefaultQueryBuilder(fessConfig, context, (f, b) -> buildMatchPhraseQuery(f, text).boost(b * boost)); } diff --git a/src/main/java/org/codelibs/fess/query/PrefixQueryCommand.java b/src/main/java/org/codelibs/fess/query/PrefixQueryCommand.java index 70adb3206..59cb835f1 100644 --- a/src/main/java/org/codelibs/fess/query/PrefixQueryCommand.java +++ b/src/main/java/org/codelibs/fess/query/PrefixQueryCommand.java @@ -55,12 +55,16 @@ public class PrefixQueryCommand extends QueryCommand { protected QueryBuilder convertPrefixQuery(final QueryContext context, final PrefixQuery prefixQuery, final float boost) { final FessConfig fessConfig = ComponentUtil.getFessConfig(); final String field = getSearchField(context.getDefaultField(), prefixQuery.getField()); + final String text = prefixQuery.getPrefix().text(); + if (Constants.DEFAULT_FIELD.equals(field)) { - context.addFieldLog(field, prefixQuery.getPrefix().text()); + context.addFieldLog(field, text + "*"); + context.addHighlightedQuery(text); return buildDefaultQueryBuilder(fessConfig, context, - (f, b) -> QueryBuilders.matchPhrasePrefixQuery(f, toLowercaseWildcard(prefixQuery.getPrefix().text())).boost(b * boost) + (f, b) -> QueryBuilders.matchPhrasePrefixQuery(f, toLowercaseWildcard(text)).boost(b * boost) .maxExpansions(fessConfig.getQueryPrefixExpansionsAsInteger()).slop(fessConfig.getQueryPrefixSlopAsInteger())); } + if (!isSearchField(field)) { final String query = prefixQuery.getPrefix().toString(); final String origQuery = toLowercaseWildcard(query); @@ -70,11 +74,13 @@ public class PrefixQueryCommand extends QueryCommand { (f, b) -> QueryBuilders.matchPhrasePrefixQuery(f, origQuery).boost(b * boost) .maxExpansions(fessConfig.getQueryPrefixExpansionsAsInteger()).slop(fessConfig.getQueryPrefixSlopAsInteger())); } - context.addFieldLog(field, prefixQuery.getPrefix().text() + "*"); + + context.addFieldLog(field, text + "*"); + context.addHighlightedQuery(text); if (getQueryFieldConfig().notAnalyzedFieldSet.contains(field)) { - return QueryBuilders.prefixQuery(field, toLowercaseWildcard(prefixQuery.getPrefix().text())).boost(boost); + return QueryBuilders.prefixQuery(field, toLowercaseWildcard(text)).boost(boost); } - return QueryBuilders.matchPhrasePrefixQuery(field, toLowercaseWildcard(prefixQuery.getPrefix().text())).boost(boost) + return QueryBuilders.matchPhrasePrefixQuery(field, toLowercaseWildcard(text)).boost(boost) .maxExpansions(fessConfig.getQueryPrefixExpansionsAsInteger()).slop(fessConfig.getQueryPrefixSlopAsInteger()); } diff --git a/src/main/java/org/codelibs/fess/query/TermRangeQueryCommand.java b/src/main/java/org/codelibs/fess/query/TermRangeQueryCommand.java index a058d77d5..c49a46559 100644 --- a/src/main/java/org/codelibs/fess/query/TermRangeQueryCommand.java +++ b/src/main/java/org/codelibs/fess/query/TermRangeQueryCommand.java @@ -17,6 +17,7 @@ package org.codelibs.fess.query; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.lucene.index.Term; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermRangeQuery; import org.apache.lucene.util.BytesRef; @@ -53,12 +54,22 @@ public class TermRangeQueryCommand extends QueryCommand { protected QueryBuilder convertTermRangeQuery(final QueryContext context, final TermRangeQuery termRangeQuery, final float boost) { final FessConfig fessConfig = ComponentUtil.getFessConfig(); final String field = getSearchField(context.getDefaultField(), termRangeQuery.getField()); + if (!isSearchField(field)) { - final String origQuery = termRangeQuery.toString(); + final StringBuilder queryBuf = new StringBuilder(); + queryBuf.append(termRangeQuery.includesLower() ? '[' : '{'); + final BytesRef lowerTerm = termRangeQuery.getLowerTerm(); + queryBuf.append(lowerTerm != null ? ("*".equals(Term.toString(lowerTerm)) ? "\\*" : Term.toString(lowerTerm)) : "*"); + queryBuf.append(" TO "); + final BytesRef upperTerm = termRangeQuery.getUpperTerm(); + queryBuf.append(upperTerm != null ? ("*".equals(Term.toString(upperTerm)) ? "\\*" : Term.toString(upperTerm)) : "*"); + queryBuf.append(termRangeQuery.includesUpper() ? ']' : '}'); + final String origQuery = queryBuf.toString(); context.addFieldLog(Constants.DEFAULT_FIELD, origQuery); context.addHighlightedQuery(origQuery); return buildDefaultQueryBuilder(fessConfig, context, (f, b) -> QueryBuilders.matchPhraseQuery(f, origQuery).boost(b)); } + context.addFieldLog(field, termRangeQuery.toString(field)); final RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(field); final BytesRef min = termRangeQuery.getLowerTerm(); diff --git a/src/main/java/org/codelibs/fess/query/WildcardQueryCommand.java b/src/main/java/org/codelibs/fess/query/WildcardQueryCommand.java index 7e07c4ecd..22831cc7b 100644 --- a/src/main/java/org/codelibs/fess/query/WildcardQueryCommand.java +++ b/src/main/java/org/codelibs/fess/query/WildcardQueryCommand.java @@ -17,6 +17,7 @@ package org.codelibs.fess.query; import java.util.Locale; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.search.Query; @@ -56,18 +57,32 @@ public class WildcardQueryCommand extends QueryCommand { final FessConfig fessConfig = ComponentUtil.getFessConfig(); final String field = getSearchField(context.getDefaultField(), wildcardQuery.getField()); if (Constants.DEFAULT_FIELD.equals(field)) { - context.addFieldLog(field, wildcardQuery.getTerm().text()); + final String text = wildcardQuery.getTerm().text(); + context.addFieldLog(field, text); + context.addHighlightedQuery(StringUtils.strip(text, "*")); return buildDefaultQueryBuilder(fessConfig, context, - (f, b) -> QueryBuilders.wildcardQuery(f, toLowercaseWildcard(wildcardQuery.getTerm().text())).boost(b * boost)); + (f, b) -> QueryBuilders.wildcardQuery(f, toLowercaseWildcard(text)).boost(b * boost)); } + if (isSearchField(field)) { - context.addFieldLog(field, wildcardQuery.getTerm().text()); - return QueryBuilders.wildcardQuery(field, toLowercaseWildcard(wildcardQuery.getTerm().text())).boost(boost); + final String text = wildcardQuery.getTerm().text(); + context.addFieldLog(field, text); + context.addHighlightedQuery(StringUtils.strip(text, "*")); + return QueryBuilders.wildcardQuery(field, toLowercaseWildcard(text)).boost(boost); } + final String query = wildcardQuery.getTerm().toString(); - final String origQuery = "*" + toLowercaseWildcard(query) + "*"; + final StringBuilder queryBuf = new StringBuilder(query.length() + 2); + if (!query.startsWith("*")) { + queryBuf.append('*'); + } + queryBuf.append(toLowercaseWildcard(query)); + if (!query.endsWith("*")) { + queryBuf.append('*'); + } + final String origQuery = queryBuf.toString(); context.addFieldLog(Constants.DEFAULT_FIELD, origQuery); - context.addHighlightedQuery(query); + context.addHighlightedQuery(StringUtils.strip(query, "*")); return buildDefaultQueryBuilder(fessConfig, context, (f, b) -> QueryBuilders.wildcardQuery(f, origQuery).boost(b * boost)); } diff --git a/src/test/java/org/codelibs/fess/helper/QueryHelperTest.java b/src/test/java/org/codelibs/fess/helper/QueryHelperTest.java index 751cd2848..48f5fa8df 100644 --- a/src/test/java/org/codelibs/fess/helper/QueryHelperTest.java +++ b/src/test/java/org/codelibs/fess/helper/QueryHelperTest.java @@ -16,6 +16,10 @@ package org.codelibs.fess.helper; import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import org.apache.lucene.analysis.core.WhitespaceAnalyzer; import org.apache.lucene.queryparser.classic.QueryParser; @@ -23,7 +27,9 @@ import org.apache.lucene.queryparser.ext.ExtendableQueryParser; import org.codelibs.core.io.FileUtil; import org.codelibs.core.misc.DynamicProperties; import org.codelibs.fess.Constants; +import org.codelibs.fess.entity.QueryContext; import org.codelibs.fess.entity.SearchRequestParams.SearchRequestType; +import org.codelibs.fess.exception.InvalidQueryException; import org.codelibs.fess.query.BooleanQueryCommand; import org.codelibs.fess.query.BoostQueryCommand; import org.codelibs.fess.query.FuzzyQueryCommand; @@ -85,57 +91,334 @@ public class QueryHelperTest extends UnitFessTestCase { new WildcardQueryCommand().register(); } - public void test_build() { + public void test_build_simple() { float titleBoost = 0.5f; float contentBoost = 0.05f; - assertQuery(functionScoreQuery(simpleQuery("QUERY", titleBoost, contentBoost)), buildQuery("QUERY")); - assertQuery(functionScoreQuery(simpleQuery("QUERY", titleBoost, contentBoost)), buildQuery(" QUERY")); - assertQuery(functionScoreQuery(simpleQuery("QUERY", titleBoost, contentBoost)), buildQuery("QUERY ")); + assertQuery(functionScoreQuery(simpleQuery("QUERY", titleBoost, contentBoost)), // + Map.of("_default", List.of("QUERY")), // + Set.of("QUERY"), // + buildQuery("QUERY")); + assertQuery(functionScoreQuery(simpleQuery("QUERY", titleBoost, contentBoost)), // + Map.of("_default", List.of("QUERY")), // + Set.of("QUERY"), // + buildQuery(" QUERY")); + assertQuery(functionScoreQuery(simpleQuery("QUERY", titleBoost, contentBoost)), // + Map.of("_default", List.of("QUERY")), // + Set.of("QUERY"), // + buildQuery("QUERY ")); + } + + public void test_build_multiple() { + float titleBoost = 0.5f; + float contentBoost = 0.05f; assertQuery( functionScoreQuery( andQuery(simpleQuery("QUERY1", titleBoost, contentBoost), simpleQuery("QUERY2", titleBoost, contentBoost))), + Map.of("_default", List.of("QUERY1", "QUERY2")), // + Set.of("QUERY1", "QUERY2"), // buildQuery("QUERY1 QUERY2")); assertQuery( functionScoreQuery( andQuery(simpleQuery("QUERY1", titleBoost, contentBoost), simpleQuery("QUERY2", titleBoost, contentBoost))), + Map.of("_default", List.of("QUERY1", "QUERY2")), // + Set.of("QUERY1", "QUERY2"), // buildQuery("QUERY1 AND QUERY2")); assertQuery( functionScoreQuery( orQuery(simpleQuery("QUERY1", titleBoost, contentBoost), simpleQuery("QUERY2", titleBoost, contentBoost))), + Map.of("_default", List.of("QUERY1", "QUERY2")), // + Set.of("QUERY1", "QUERY2"), // buildQuery("QUERY1 OR QUERY2")); - assertEquals( - "{\"function_score\":{\"query\":{\"prefix\":{\"site\":{\"value\":\"fess.codelibs.org\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("site:fess.codelibs.org").toString().replaceAll("\\s", "")); + } - assertEquals( + public void test_build_boost() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"QUERY1\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":5.0}}},{\"match_phrase\":{\"content\":{\"query\":\"QUERY1\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"fuzzy\":{\"title\":{\"value\":\"QUERY1\",\"fuzziness\":\"AUTO\",\"prefix_length\":0,\"max_expansions\":10,\"transpositions\":true,\"boost\":0.01}}},{\"fuzzy\":{\"content\":{\"value\":\"QUERY1\",\"fuzziness\":\"AUTO\",\"prefix_length\":0,\"max_expansions\":10,\"transpositions\":true,\"boost\":0.005}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("QUERY1")), // + Set.of("QUERY1"), // + buildQuery("QUERY1^10")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"must\":[{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"QUERY1\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":5.0}}},{\"match_phrase\":{\"content\":{\"query\":\"QUERY1\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"fuzzy\":{\"title\":{\"value\":\"QUERY1\",\"fuzziness\":\"AUTO\",\"prefix_length\":0,\"max_expansions\":10,\"transpositions\":true,\"boost\":0.01}}},{\"fuzzy\":{\"content\":{\"value\":\"QUERY1\",\"fuzziness\":\"AUTO\",\"prefix_length\":0,\"max_expansions\":10,\"transpositions\":true,\"boost\":0.005}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"QUERY2\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":2.5}}},{\"match_phrase\":{\"content\":{\"query\":\"QUERY2\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.25}}},{\"fuzzy\":{\"title\":{\"value\":\"QUERY2\",\"fuzziness\":\"AUTO\",\"prefix_length\":0,\"max_expansions\":10,\"transpositions\":true,\"boost\":0.01}}},{\"fuzzy\":{\"content\":{\"value\":\"QUERY2\",\"fuzziness\":\"AUTO\",\"prefix_length\":0,\"max_expansions\":10,\"transpositions\":true,\"boost\":0.005}}}],\"adjust_pure_negative\":true,\"boost\":1.0}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("QUERY1", "QUERY2")), // + Set.of("QUERY1", "QUERY2"), // + buildQuery("QUERY1^10 QUERY2^5")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"match_phrase\":{\"title\":{\"query\":\"QUERY1\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":10.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("QUERY1")), // + Set.of("QUERY1"), // + buildQuery("title:QUERY1^10")); + } + + public void test_build_wildcard() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"wildcard\":{\"title\":{\"wildcard\":\"*\",\"boost\":0.5}}},{\"wildcard\":{\"content\":{\"wildcard\":\"*\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("*")), // + Set.of(), // + buildQuery("*")); + + assertQueryContext( "{\"function_score\":{\"query\":{\"wildcard\":{\"title\":{\"wildcard\":\"*\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("allintitle:").toString().replaceAll("\\s", "")); - assertEquals( - "{\"function_score\":{\"query\":{\"match_phrase\":{\"title\":{\"query\":\"test\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("allintitle:test").toString().replaceAll("\\s", "")); - assertEquals( - "{\"function_score\":{\"query\":{\"match_phrase\":{\"title\":{\"query\":\"test\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("allintitle: test").toString().replaceAll("\\s", "")); - assertEquals( - "{\"function_score\":{\"query\":{\"bool\":{\"must\":[{\"match_phrase\":{\"title\":{\"query\":\"aaa\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}},{\"match_phrase\":{\"title\":{\"query\":\"bbb\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("allintitle: aaa bbb").toString().replaceAll("\\s", "")); + Map.of("title", List.of("*")), // + Set.of(), // + buildQuery("title:*")); - assertEquals( + assertQueryContext( + "{\"function_score\":{\"query\":{\"wildcard\":{\"title\":{\"wildcard\":\"*aaa*\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("*aaa*")), // + Set.of("aaa"), // + buildQuery("title:*aaa*")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"wildcard\":{\"title\":{\"wildcard\":\"*aaa:*\",\"boost\":0.5}}},{\"wildcard\":{\"content\":{\"wildcard\":\"*aaa:*\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("*aaa:*")), // + Set.of("aaa:"), // + buildQuery("aaa:*")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"wildcard\":{\"title\":{\"wildcard\":\"*aaa*\",\"boost\":0.5}}},{\"wildcard\":{\"content\":{\"wildcard\":\"*aaa*\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("*aaa*")), // + Set.of("aaa"), // + buildQuery("*aaa*")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"wildcard\":{\"title\":{\"wildcard\":\"*aaa:*bbb*\",\"boost\":0.5}}},{\"wildcard\":{\"content\":{\"wildcard\":\"*aaa:*bbb*\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("*aaa:*bbb*")), // + Set.of("aaa:*bbb"), // + buildQuery("aaa:*bbb*")); + } + + public void test_build_phrase() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"QUERY1QUERY2\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase\":{\"content\":{\"query\":\"QUERY1QUERY2\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("QUERY1 QUERY2")), // + Set.of("QUERY1", "QUERY2"), // + buildQuery("\"QUERY1 QUERY2\"")); + assertQueryContext(buildQuery("\"QUERY1 QUERY2\"").getQueryBuilder().toString().replaceAll("\\s", ""), + buildQuery("aaa:\"QUERY1 QUERY2\"")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"match_phrase\":{\"title\":{\"query\":\"QUERY1QUERY2\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("QUERY1 QUERY2")), // + Set.of("QUERY1", "QUERY2"), // + buildQuery("title:\"QUERY1 QUERY2\"")); + } + + public void test_build_prefix() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase_prefix\":{\"title\":{\"query\":\"query\",\"slop\":0,\"max_expansions\":50,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase_prefix\":{\"content\":{\"query\":\"query\",\"slop\":0,\"max_expansions\":50,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("QUERY*")), // + Set.of("QUERY"), // + buildQuery("QUERY*")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"match_phrase_prefix\":{\"title\":{\"query\":\"query\",\"slop\":0,\"max_expansions\":50,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("QUERY*")), // + Set.of("QUERY"), // + buildQuery("title:QUERY*")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"prefix\":{\"url\":{\"value\":\"query\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("url", List.of("QUERY*")), // + Set.of("QUERY"), // + buildQuery("url:QUERY*")); + assertQueryContext(buildQuery("url:QUERY*").getQueryBuilder().toString().replaceAll("\\s", ""), buildQuery("url:\"QUERY*\"")); + + } + + public void test_build_escape() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"aaa:bbb\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase\":{\"content\":{\"query\":\"aaa:bbb\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}},{\"fuzzy\":{\"title\":{\"value\":\"aaa:bbb\",\"fuzziness\":\"AUTO\",\"prefix_length\":0,\"max_expansions\":10,\"transpositions\":true,\"boost\":0.01}}},{\"fuzzy\":{\"content\":{\"value\":\"aaa:bbb\",\"fuzziness\":\"AUTO\",\"prefix_length\":0,\"max_expansions\":10,\"transpositions\":true,\"boost\":0.005}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("aaa:bbb")), // + Set.of("aaa:bbb"), // + buildQuery("aaa\\:bbb")); + assertQueryContext(buildQuery("aaa\\:bbb").getQueryBuilder().toString().replaceAll("\\s", ""), buildQuery("\"aaa\\:bbb\"")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"match_phrase\":{\"title\":{\"query\":\"aaa:bbb\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("aaa:bbb")), // + Set.of("aaa:bbb"), // + buildQuery("title:aaa\\:bbb")); + } + + public void test_build_site() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"prefix\":{\"site\":{\"value\":\"fess.codelibs.org\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("site", List.of("fess.codelibs.org*")), // + Set.of("fess.codelibs.org"), // + buildQuery("site:fess.codelibs.org")); + } + + public void test_build_allintitle() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"wildcard\":{\"title\":{\"wildcard\":\"*\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("*")), // + Set.of(), // + buildQuery("allintitle:")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"match_phrase\":{\"title\":{\"query\":\"test\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("test")), // + Set.of("test"), // + buildQuery("allintitle:test")); + assertQueryContext(buildQuery("allintitle:test").getQueryBuilder().toString().replaceAll("\\s", ""), + buildQuery("allintitle: test")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"must\":[{\"match_phrase\":{\"title\":{\"query\":\"aaa\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}},{\"match_phrase\":{\"title\":{\"query\":\"bbb\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":1.0}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("aaa", "bbb")), // + Set.of("aaa", "bbb"), // + buildQuery("allintitle: aaa bbb")); + } + + public void test_build_allinurl() { + assertQueryContext( "{\"function_score\":{\"query\":{\"wildcard\":{\"url\":{\"wildcard\":\"*\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("allinurl:").toString().replaceAll("\\s", "")); - assertEquals( + Map.of("url", List.of("*")), // + Set.of(), // + buildQuery("allinurl:")); + + assertQueryContext( "{\"function_score\":{\"query\":{\"wildcard\":{\"url\":{\"wildcard\":\"*test*\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("allinurl:test").toString().replaceAll("\\s", "")); - assertEquals( - "{\"function_score\":{\"query\":{\"wildcard\":{\"url\":{\"wildcard\":\"*test*\",\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("allinurl: test").toString().replaceAll("\\s", "")); - assertEquals( + Map.of("url", List.of("*test*")), // + Set.of("test"), // + buildQuery("allinurl:test")); + assertQueryContext(buildQuery("allinurl:test").getQueryBuilder().toString().replaceAll("\\s", ""), buildQuery("allinurl: test")); + + assertQueryContext( "{\"function_score\":{\"query\":{\"bool\":{\"must\":[{\"wildcard\":{\"url\":{\"wildcard\":\"*aaa*\",\"boost\":1.0}}},{\"wildcard\":{\"url\":{\"wildcard\":\"*bbb*\",\"boost\":1.0}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", - buildQuery("allinurl: aaa bbb").toString().replaceAll("\\s", "")); + Map.of("url", List.of("*aaa*", "*bbb*")), // + Set.of("aaa", "bbb"), // + buildQuery("allinurl: aaa bbb")); + } + + public void test_build_sort() { + String query = + "{\"function_score\":{\"query\":{\"match_all\":{\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}"; + assertQueryContext(query, Map.of(), // + Set.of(), // + "{\"timestamp\":{\"order\":\"asc\"}}", // + buildQuery("sort:timestamp")); + assertQueryContext(query, Map.of(), // + Set.of(), // + "{\"timestamp\":{\"order\":\"asc\"}}", // + buildQuery("sort:timestamp.asc")); + assertQueryContext(query, Map.of(), // + Set.of(), // + "{\"timestamp\":{\"order\":\"desc\"}}", // + buildQuery("sort:timestamp.desc")); + + assertQueryContext(query, Map.of(), // + Set.of(), // + "{\"timestamp\":{\"order\":\"desc\"}}{\"last_modified\":{\"order\":\"asc\"}}", // + buildQuery("sort:timestamp.desc sort:last_modified")); + assertQueryContext(query, Map.of(), // + Set.of(), // + "{\"timestamp\":{\"order\":\"desc\"}}{\"last_modified\":{\"order\":\"desc\"}}", // + buildQuery("sort:timestamp.desc sort:last_modified.desc")); + + assertQueryContext(query, Map.of(), // + Set.of(), // + "{\"timestamp\":{\"order\":\"asc\"}}", // + buildQuery("sort:timestamp.xxx")); + + try { + buildQuery("sort:aaa"); + fail(); + } catch (InvalidQueryException e) { + // ok + } + } + + public void test_build_fuzzy() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"fuzzy\":{\"title\":{\"value\":\"QUERY1\",\"fuzziness\":\"2\",\"prefix_length\":0,\"max_expansions\":50,\"transpositions\":true,\"boost\":0.5}}},{\"fuzzy\":{\"content\":{\"value\":\"QUERY1\",\"fuzziness\":\"2\",\"prefix_length\":0,\"max_expansions\":50,\"transpositions\":true,\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("QUERY1")), // + Set.of("QUERY1"), // + buildQuery("QUERY1~0.5")); + assertQuery(buildQuery("QUERY1~0.5").getQueryBuilder(), // + buildQuery("QUERY1~")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"fuzzy\":{\"title\":{\"value\":\"QUERY1\",\"fuzziness\":\"2\",\"prefix_length\":0,\"max_expansions\":50,\"transpositions\":true,\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("title", List.of("QUERY1")), // + Set.of("QUERY1"), // + buildQuery("title:QUERY1~0.5")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"fuzzy\":{\"title\":{\"value\":\"aaa:QUERY1\",\"fuzziness\":\"2\",\"prefix_length\":0,\"max_expansions\":50,\"transpositions\":true,\"boost\":0.5}}},{\"fuzzy\":{\"content\":{\"value\":\"aaa:QUERY1\",\"fuzziness\":\"2\",\"prefix_length\":0,\"max_expansions\":50,\"transpositions\":true,\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("aaa:QUERY1")), // + Set.of("aaa:QUERY1"), // + buildQuery("aaa:QUERY1~0.5")); + } + + public void test_build_range() { + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"[aaaTObbb]\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase\":{\"content\":{\"query\":\"[aaaTObbb]\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("[aaa TO bbb]")), // + Set.of("[aaa TO bbb]"), // + buildQuery("[aaa TO bbb]")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"[*TObbb]\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase\":{\"content\":{\"query\":\"[*TObbb]\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("[* TO bbb]")), // + Set.of("[* TO bbb]"), // + buildQuery("[* TO bbb]")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"[aaaTO*]\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase\":{\"content\":{\"query\":\"[aaaTO*]\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("[aaa TO *]")), // + Set.of("[aaa TO *]"), // + buildQuery("[aaa TO *]")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"{aaaTObbb}\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase\":{\"content\":{\"query\":\"{aaaTObbb}\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("{aaa TO bbb}")), // + Set.of("{aaa TO bbb}"), // + buildQuery("{aaa TO bbb}")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"{*TObbb}\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase\":{\"content\":{\"query\":\"{*TObbb}\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("{* TO bbb}")), // + Set.of("{* TO bbb}"), // + buildQuery("{* TO bbb}")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"bool\":{\"should\":[{\"match_phrase\":{\"title\":{\"query\":\"{aaaTO*}\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.5}}},{\"match_phrase\":{\"content\":{\"query\":\"{aaaTO*}\",\"slop\":0,\"zero_terms_query\":\"NONE\",\"boost\":0.05}}}],\"adjust_pure_negative\":true,\"boost\":1.0}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("_default", List.of("{aaa TO *}")), // + Set.of("{aaa TO *}"), // + buildQuery("{aaa TO *}")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"range\":{\"timestamp\":{\"from\":\"0\",\"to\":\"100\",\"include_lower\":true,\"include_upper\":true,\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("timestamp", List.of("[0 TO 100]")), // + Set.of(), // + buildQuery("timestamp:[0 TO 100]")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"range\":{\"timestamp\":{\"from\":null,\"to\":\"100\",\"include_lower\":true,\"include_upper\":true,\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("timestamp", List.of("[* TO 100]")), // + Set.of(), // + buildQuery("timestamp:[* TO 100]")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"range\":{\"timestamp\":{\"from\":\"0\",\"to\":null,\"include_lower\":true,\"include_upper\":true,\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("timestamp", List.of("[0 TO *]")), // + Set.of(), // + buildQuery("timestamp:[0 TO *]")); + + assertQueryContext( + "{\"function_score\":{\"query\":{\"range\":{\"timestamp\":{\"from\":\"0\",\"to\":\"100\",\"include_lower\":false,\"include_upper\":false,\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("timestamp", List.of("{0 TO 100}")), // + Set.of(), // + buildQuery("timestamp:{0 TO 100}")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"range\":{\"timestamp\":{\"from\":null,\"to\":\"100\",\"include_lower\":true,\"include_upper\":false,\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("timestamp", List.of("{* TO 100}")), // + Set.of(), // + buildQuery("timestamp:{* TO 100}")); + assertQueryContext( + "{\"function_score\":{\"query\":{\"range\":{\"timestamp\":{\"from\":\"0\",\"to\":null,\"include_lower\":false,\"include_upper\":true,\"boost\":1.0}}},\"functions\":[{\"filter\":{\"match_all\":{\"boost\":1.0}},\"field_value_factor\":{\"field\":\"boost\",\"factor\":1.0,\"modifier\":\"none\"}}],\"score_mode\":\"multiply\",\"max_boost\":3.4028235E38,\"boost\":1.0}}", + Map.of("timestamp", List.of("{0 TO *}")), // + Set.of(), // + buildQuery("timestamp:{0 TO *}")); } private QueryBuilder andQuery(QueryBuilder... queries) { @@ -167,14 +450,59 @@ public class QueryHelperTest extends UnitFessTestCase { return QueryBuilders.functionScoreQuery(queryBuilder, ScoreFunctionBuilders.fieldValueFactorFunction("boost")); } - private void assertQuery(QueryBuilder query1, QueryBuilder query2) { - assertEquals(query1.toString(), query2.toString()); + private void assertQuery(QueryBuilder query1, QueryContext context) { + assertQuery(query1, null, null, context); } - private QueryBuilder buildQuery(String query) { + private void assertQuery(QueryBuilder query1, Map> fieldLogMap, Set highlightedQuerySet, + QueryContext context) { + assertEquals(query1.toString(), context.getQueryBuilder().toString()); + assertFieldLogs(fieldLogMap); + assertHighlightedQueries(highlightedQuerySet); + } + + private void assertQueryContext(String query, QueryContext context) { + assertQueryContext(query, null, null, context); + } + + private void assertQueryContext(String query, Map> fieldLogMap, Set highlightedQuerySet, + QueryContext context) { + assertQueryContext(query, fieldLogMap, highlightedQuerySet, null, context); + } + + private void assertQueryContext(String query, Map> fieldLogMap, Set highlightedQuerySet, String sorts, + QueryContext context) { + assertEquals(query, context.getQueryBuilder().toString().replaceAll("\\s", "")); + assertFieldLogs(fieldLogMap); + assertHighlightedQueries(highlightedQuerySet); + if (sorts != null) { + assertEquals(sorts, context.sortBuilders().stream().map(s -> s.toString().replaceAll("\\s", "")).collect(Collectors.joining())); + } + } + + private void assertHighlightedQueries(Set highlightedQuerySet) { + @SuppressWarnings("unchecked") + Set set = (Set) getMockRequest().getAttribute(Constants.HIGHLIGHT_QUERIES); + if (highlightedQuerySet != null) { + assertEquals(highlightedQuerySet.stream().sorted().collect(Collectors.joining("\n")), + set.stream().sorted().collect(Collectors.joining("\n"))); + } + set.clear(); + } + + private void assertFieldLogs(Map> fieldLogMap) { + @SuppressWarnings("unchecked") + Map> map = (Map>) getMockRequest().getAttribute(Constants.FIELD_LOGS); + if (fieldLogMap != null) { + assertEquals(fieldLogMap, map); + } + map.clear(); + } + + private QueryContext buildQuery(String query) { return queryHelper.build(SearchRequestType.SEARCH, query, context -> { context.skipRoleQuery(); - }).getQueryBuilder(); + }); } } \ No newline at end of file