Skip to content

Commit 5d29f25

Browse files
Group by analyzer
1 parent dab5f36 commit 5d29f25

File tree

1 file changed

+31
-29
lines changed

1 file changed

+31
-29
lines changed

server/src/main/java/org/elasticsearch/index/query/MultiFieldMatchQueryBuilder.java

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import java.io.IOException;
4444
import java.util.ArrayList;
45+
import java.util.HashMap;
4546
import java.util.List;
4647
import java.util.Map;
4748
import java.util.Objects;
@@ -292,8 +293,7 @@ protected Query doToQuery(SearchExecutionContext context) throws IOException {
292293

293294
validateSimilarity(context, fields);
294295

295-
Analyzer sharedAnalyzer = null;
296-
List<MultiFieldMatchQueryBuilder.FieldAndBoost> fieldsAndBoosts = new ArrayList<>();
296+
Map<Analyzer, List<FieldAndBoost>> groups = new HashMap<>();
297297
for (Map.Entry<String, Float> entry : fields.entrySet()) {
298298
String name = entry.getKey();
299299
MappedFieldType fieldType = context.getFieldType(name);
@@ -308,37 +308,39 @@ protected Query doToQuery(SearchExecutionContext context) throws IOException {
308308
}
309309

310310
float boost = entry.getValue() == null ? 1.0f : entry.getValue();
311-
fieldsAndBoosts.add(new MultiFieldMatchQueryBuilder.FieldAndBoost(fieldType, boost));
312311

313-
// TODO: group by analyzer.
314312
Analyzer analyzer = fieldType.getTextSearchInfo().searchAnalyzer();
315-
if (sharedAnalyzer != null && analyzer.equals(sharedAnalyzer) == false) {
316-
throw new IllegalArgumentException("All fields in [" + NAME + "] query must have the same search analyzer");
313+
if (groups.containsKey(analyzer) == false) {
314+
groups.put(analyzer, new ArrayList<>());
317315
}
318-
sharedAnalyzer = analyzer;
316+
groups.get(analyzer).add(new FieldAndBoost(fieldType, boost));
319317
}
320318

321-
assert fieldsAndBoosts.isEmpty() == false;
322-
String placeholderFieldName = fieldsAndBoosts.get(0).fieldType.name();
323-
boolean canGenerateSynonymsPhraseQuery = autoGenerateSynonymsPhraseQuery;
324-
for (MultiFieldMatchQueryBuilder.FieldAndBoost fieldAndBoost : fieldsAndBoosts) {
325-
TextSearchInfo textSearchInfo = fieldAndBoost.fieldType.getTextSearchInfo();
326-
canGenerateSynonymsPhraseQuery &= textSearchInfo.hasPositions();
327-
}
319+
// TODO: For now assume we have one group.
320+
assert groups.size() == 1;
328321

329-
MultiFieldMatchQueryBuilder.CombinedFieldsBuilder builder = new MultiFieldMatchQueryBuilder.CombinedFieldsBuilder(
330-
fieldsAndBoosts,
331-
sharedAnalyzer,
332-
canGenerateSynonymsPhraseQuery,
333-
context
334-
);
335-
Query query = builder.createBooleanQuery(placeholderFieldName, value.toString(), operator.toBooleanClauseOccur());
322+
List<Query> queries = new ArrayList<>();
323+
for (Map.Entry<Analyzer, List<FieldAndBoost>> group : groups.entrySet()) {
324+
var fieldsAndBoosts = group.getValue();
325+
326+
String placeholderFieldName = fieldsAndBoosts.get(0).fieldType.name();
327+
boolean canGenerateSynonymsPhraseQuery = autoGenerateSynonymsPhraseQuery;
328+
for (FieldAndBoost fieldAndBoost : fieldsAndBoosts) {
329+
TextSearchInfo textSearchInfo = fieldAndBoost.fieldType.getTextSearchInfo();
330+
canGenerateSynonymsPhraseQuery &= textSearchInfo.hasPositions();
331+
}
336332

337-
query = Queries.maybeApplyMinimumShouldMatch(query, minimumShouldMatch);
338-
if (query == null) {
339-
query = zeroTermsQuery.asQuery();
333+
var builder = new CombinedFieldsBuilder(fieldsAndBoosts, group.getKey(), canGenerateSynonymsPhraseQuery, context);
334+
Query query = builder.createBooleanQuery(placeholderFieldName, value.toString(), operator.toBooleanClauseOccur());
335+
336+
query = Queries.maybeApplyMinimumShouldMatch(query, minimumShouldMatch);
337+
if (query == null) {
338+
query = zeroTermsQuery.asQuery();
339+
}
340340
}
341-
return query;
341+
342+
// TODO: combine queries.
343+
return queries.getFirst();
342344
}
343345

344346
private static void validateSimilarity(SearchExecutionContext context, Map<String, Float> fields) {
@@ -367,11 +369,11 @@ private static final class FieldAndBoost {
367369
}
368370

369371
private static class CombinedFieldsBuilder extends QueryBuilder {
370-
private final List<MultiFieldMatchQueryBuilder.FieldAndBoost> fields;
372+
private final List<FieldAndBoost> fields;
371373
private final SearchExecutionContext context;
372374

373375
CombinedFieldsBuilder(
374-
List<MultiFieldMatchQueryBuilder.FieldAndBoost> fields,
376+
List<FieldAndBoost> fields,
375377
Analyzer analyzer,
376378
boolean autoGenerateSynonymsPhraseQuery,
377379
SearchExecutionContext context
@@ -411,7 +413,7 @@ protected Query newSynonymQuery(String field, TermAndBoost[] terms) {
411413
BytesRef bytes = termAndBoost.term();
412414
query.addTerm(bytes);
413415
}
414-
for (MultiFieldMatchQueryBuilder.FieldAndBoost fieldAndBoost : fields) {
416+
for (FieldAndBoost fieldAndBoost : fields) {
415417
MappedFieldType fieldType = fieldAndBoost.fieldType;
416418
float fieldBoost = fieldAndBoost.boost;
417419
query.addField(fieldType.name(), fieldBoost);
@@ -428,7 +430,7 @@ protected Query newTermQuery(Term term, float boost) {
428430
@Override
429431
protected Query analyzePhrase(String field, TokenStream stream, int slop) throws IOException {
430432
BooleanQuery.Builder builder = new BooleanQuery.Builder();
431-
for (MultiFieldMatchQueryBuilder.FieldAndBoost fieldAndBoost : fields) {
433+
for (FieldAndBoost fieldAndBoost : fields) {
432434
Query query = fieldAndBoost.fieldType.phraseQuery(stream, slop, enablePositionIncrements, context);
433435
if (fieldAndBoost.boost != 1f) {
434436
query = new BoostQuery(query, fieldAndBoost.boost);

0 commit comments

Comments
 (0)