|
@@ -12,6 +12,7 @@ import org.apache.lucene.analysis.Analyzer;
|
|
import org.apache.lucene.analysis.TokenStream;
|
|
import org.apache.lucene.analysis.TokenStream;
|
|
import org.apache.lucene.index.Term;
|
|
import org.apache.lucene.index.Term;
|
|
import org.apache.lucene.queries.BlendedTermQuery;
|
|
import org.apache.lucene.queries.BlendedTermQuery;
|
|
|
|
+import org.apache.lucene.search.BooleanClause;
|
|
import org.apache.lucene.search.BoostQuery;
|
|
import org.apache.lucene.search.BoostQuery;
|
|
import org.apache.lucene.search.DisjunctionMaxQuery;
|
|
import org.apache.lucene.search.DisjunctionMaxQuery;
|
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
|
@@ -66,7 +67,7 @@ public class MultiMatchQueryParser extends MatchQueryParser {
|
|
break;
|
|
break;
|
|
|
|
|
|
case CROSS_FIELDS:
|
|
case CROSS_FIELDS:
|
|
- queries = buildCrossFieldQuery(type, fieldNames, value, minimumShouldMatch, tieBreaker);
|
|
|
|
|
|
+ queries = buildCrossFieldQuery(fieldNames, value, minimumShouldMatch, tieBreaker);
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -108,15 +109,16 @@ public class MultiMatchQueryParser extends MatchQueryParser {
|
|
return queries;
|
|
return queries;
|
|
}
|
|
}
|
|
|
|
|
|
- private List<Query> buildCrossFieldQuery(MultiMatchQueryBuilder.Type type, Map<String, Float> fieldNames,
|
|
|
|
- Object value, String minimumShouldMatch, float tieBreaker) throws IOException {
|
|
|
|
|
|
+ private List<Query> buildCrossFieldQuery(Map<String, Float> fieldNames,
|
|
|
|
+ Object value, String minimumShouldMatch, float tieBreaker) {
|
|
|
|
+
|
|
Map<Analyzer, List<FieldAndBoost>> groups = new HashMap<>();
|
|
Map<Analyzer, List<FieldAndBoost>> groups = new HashMap<>();
|
|
List<Query> queries = new ArrayList<>();
|
|
List<Query> queries = new ArrayList<>();
|
|
for (Map.Entry<String, Float> entry : fieldNames.entrySet()) {
|
|
for (Map.Entry<String, Float> entry : fieldNames.entrySet()) {
|
|
String name = entry.getKey();
|
|
String name = entry.getKey();
|
|
MappedFieldType fieldType = context.getFieldType(name);
|
|
MappedFieldType fieldType = context.getFieldType(name);
|
|
if (fieldType != null) {
|
|
if (fieldType != null) {
|
|
- Analyzer actualAnalyzer = getAnalyzer(fieldType, type == MultiMatchQueryBuilder.Type.PHRASE);
|
|
|
|
|
|
+ Analyzer actualAnalyzer = getAnalyzer(fieldType, false);
|
|
if (groups.containsKey(actualAnalyzer) == false) {
|
|
if (groups.containsKey(actualAnalyzer) == false) {
|
|
groups.put(actualAnalyzer, new ArrayList<>());
|
|
groups.put(actualAnalyzer, new ArrayList<>());
|
|
}
|
|
}
|
|
@@ -130,7 +132,7 @@ public class MultiMatchQueryParser extends MatchQueryParser {
|
|
builder = new MatchQueryBuilder(group.getKey(), group.getValue().get(0).fieldType,
|
|
builder = new MatchQueryBuilder(group.getKey(), group.getValue().get(0).fieldType,
|
|
enablePositionIncrements, autoGenerateSynonymsPhraseQuery);
|
|
enablePositionIncrements, autoGenerateSynonymsPhraseQuery);
|
|
} else {
|
|
} else {
|
|
- builder = new BlendedQueryBuilder(group.getKey(), group.getValue(), tieBreaker,
|
|
|
|
|
|
+ builder = new CrossFieldsQueryBuilder(group.getKey(), group.getValue(), tieBreaker,
|
|
enablePositionIncrements, autoGenerateSynonymsPhraseQuery);
|
|
enablePositionIncrements, autoGenerateSynonymsPhraseQuery);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -140,7 +142,11 @@ public class MultiMatchQueryParser extends MatchQueryParser {
|
|
* fields are already grouped by their analyzers/types.
|
|
* fields are already grouped by their analyzers/types.
|
|
*/
|
|
*/
|
|
String representativeField = group.getValue().get(0).fieldType.name();
|
|
String representativeField = group.getValue().get(0).fieldType.name();
|
|
- Query query = parseInternal(type.matchQueryType(), representativeField, builder, value);
|
|
|
|
|
|
+ Query query = builder.createBooleanQuery(representativeField, value.toString(), occur);
|
|
|
|
+ if (query == null) {
|
|
|
|
+ query = zeroTermsQuery();
|
|
|
|
+ }
|
|
|
|
+
|
|
query = Queries.maybeApplyMinimumShouldMatch(query, minimumShouldMatch);
|
|
query = Queries.maybeApplyMinimumShouldMatch(query, minimumShouldMatch);
|
|
if (query != null) {
|
|
if (query != null) {
|
|
if (group.getValue().size() == 1) {
|
|
if (group.getValue().size() == 1) {
|
|
@@ -157,17 +163,32 @@ public class MultiMatchQueryParser extends MatchQueryParser {
|
|
return queries;
|
|
return queries;
|
|
}
|
|
}
|
|
|
|
|
|
- private class BlendedQueryBuilder extends MatchQueryBuilder {
|
|
|
|
|
|
+ private class CrossFieldsQueryBuilder extends MatchQueryBuilder {
|
|
private final List<FieldAndBoost> blendedFields;
|
|
private final List<FieldAndBoost> blendedFields;
|
|
private final float tieBreaker;
|
|
private final float tieBreaker;
|
|
|
|
|
|
- BlendedQueryBuilder(Analyzer analyzer, List<FieldAndBoost> blendedFields, float tieBreaker,
|
|
|
|
|
|
+ CrossFieldsQueryBuilder(Analyzer analyzer, List<FieldAndBoost> blendedFields, float tieBreaker,
|
|
boolean enablePositionIncrements, boolean autoGenerateSynonymsPhraseQuery) {
|
|
boolean enablePositionIncrements, boolean autoGenerateSynonymsPhraseQuery) {
|
|
super(analyzer, blendedFields.get(0).fieldType, enablePositionIncrements, autoGenerateSynonymsPhraseQuery);
|
|
super(analyzer, blendedFields.get(0).fieldType, enablePositionIncrements, autoGenerateSynonymsPhraseQuery);
|
|
this.blendedFields = blendedFields;
|
|
this.blendedFields = blendedFields;
|
|
this.tieBreaker = tieBreaker;
|
|
this.tieBreaker = tieBreaker;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public Query createPhraseQuery(String field, String queryText, int phraseSlop) {
|
|
|
|
+ throw new IllegalArgumentException("[multi_match] queries in [cross_fields] mode don't support phrases");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected Query createPhrasePrefixQuery(String field, String queryText, int slop) {
|
|
|
|
+ throw new IllegalArgumentException("[multi_match] queries in [cross_fields] mode don't support phrase prefix");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ protected Query createBooleanPrefixQuery(String field, String queryText, BooleanClause.Occur occur) {
|
|
|
|
+ throw new IllegalArgumentException("[multi_match] queries in [cross_fields] mode don't support boolean prefix");
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
protected Query newSynonymQuery(TermAndBoost[] terms) {
|
|
protected Query newSynonymQuery(TermAndBoost[] terms) {
|
|
BytesRef[] values = new BytesRef[terms.length];
|
|
BytesRef[] values = new BytesRef[terms.length];
|
|
@@ -184,15 +205,7 @@ public class MultiMatchQueryParser extends MatchQueryParser {
|
|
|
|
|
|
@Override
|
|
@Override
|
|
protected Query newPrefixQuery(Term term) {
|
|
protected Query newPrefixQuery(Term term) {
|
|
- List<Query> disjunctions = new ArrayList<>();
|
|
|
|
- for (FieldAndBoost fieldType : blendedFields) {
|
|
|
|
- Query query = fieldType.fieldType.prefixQuery(term.text(), null, context);
|
|
|
|
- if (fieldType.boost != 1f) {
|
|
|
|
- query = new BoostQuery(query, fieldType.boost);
|
|
|
|
- }
|
|
|
|
- disjunctions.add(query);
|
|
|
|
- }
|
|
|
|
- return new DisjunctionMaxQuery(disjunctions, tieBreaker);
|
|
|
|
|
|
+ throw new IllegalArgumentException("[multi_match] queries in [cross_fields] mode don't support prefix");
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|