1010package org .elasticsearch .index .query ;
1111
1212import org .apache .lucene .analysis .Analyzer ;
13- import org .apache .lucene .analysis .TokenStream ;
14- import org .apache .lucene .index .Term ;
15- import org .apache .lucene .sandbox .search .CombinedFieldQuery ;
16- import org .apache .lucene .search .BooleanClause ;
17- import org .apache .lucene .search .BooleanQuery ;
18- import org .apache .lucene .search .BoostAttribute ;
19- import org .apache .lucene .search .BoostQuery ;
2013import org .apache .lucene .search .Query ;
2114import org .apache .lucene .search .similarities .BM25Similarity ;
2215import org .apache .lucene .search .similarities .Similarity ;
23- import org .apache .lucene .util .BytesRef ;
24- import org .apache .lucene .util .QueryBuilder ;
2516import org .elasticsearch .TransportVersion ;
2617import org .elasticsearch .TransportVersions ;
2718import org .elasticsearch .common .Strings ;
3021import org .elasticsearch .common .lucene .search .Queries ;
3122import org .elasticsearch .index .mapper .MappedFieldType ;
3223import org .elasticsearch .index .mapper .TextFieldMapper ;
33- import org .elasticsearch .index .mapper .TextSearchInfo ;
3424import org .elasticsearch .index .search .QueryParserHelper ;
35- import org .elasticsearch .lucene .analysis .miscellaneous .DisableGraphAttribute ;
3625import org .elasticsearch .lucene .similarity .LegacyBM25Similarity ;
3726import org .elasticsearch .xcontent .ConstructingObjectParser ;
3827import org .elasticsearch .xcontent .ObjectParser ;
@@ -293,7 +282,7 @@ protected Query doToQuery(SearchExecutionContext context) throws IOException {
293282
294283 validateSimilarity (context , fields );
295284
296- Map <Analyzer , List <FieldAndBoost >> groups = new HashMap <>();
285+ Map <Analyzer , List <String >> groups = new HashMap <>();
297286 for (Map .Entry <String , Float > entry : fields .entrySet ()) {
298287 String name = entry .getKey ();
299288 MappedFieldType fieldType = context .getFieldType (name );
@@ -307,41 +296,43 @@ protected Query doToQuery(SearchExecutionContext context) throws IOException {
307296 );
308297 }
309298
310- float boost = entry . getValue () == null ? 1.0f : entry . getValue ();
299+ // TODO: handle per-field boosts.
311300
312301 Analyzer analyzer = fieldType .getTextSearchInfo ().searchAnalyzer ();
313302 if (groups .containsKey (analyzer ) == false ) {
314303 groups .put (analyzer , new ArrayList <>());
315304 }
316- groups .get (analyzer ).add (new FieldAndBoost ( fieldType , boost ) );
305+ groups .get (analyzer ).add (name );
317306 }
318307
319308 // TODO: For now assume we have one group.
320309 assert groups .size () == 1 ;
321310
322- List < Query > queries = new ArrayList <> ();
323- for (Map .Entry <Analyzer , List <FieldAndBoost >> group : groups .entrySet ()) {
324- var fieldsAndBoosts = group . getValue ();
325-
311+ var disMax = new DisMaxQueryBuilder ();
312+ for (Map .Entry <Analyzer , List <String >> group : groups .entrySet ()) {
313+ /*
314+ TODO
326315 String placeholderFieldName = fieldsAndBoosts.get(0).fieldType.name();
327316 boolean canGenerateSynonymsPhraseQuery = autoGenerateSynonymsPhraseQuery;
328317 for (FieldAndBoost fieldAndBoost : fieldsAndBoosts) {
329318 TextSearchInfo textSearchInfo = fieldAndBoost.fieldType.getTextSearchInfo();
330319 canGenerateSynonymsPhraseQuery &= textSearchInfo.hasPositions();
331320 }
321+ */
332322
333- var builder = new CombinedFieldsBuilder ( fieldsAndBoosts , group .getKey (), canGenerateSynonymsPhraseQuery , context );
334- Query query = builder . createBooleanQuery ( placeholderFieldName , value . toString (), operator . toBooleanClauseOccur ());
323+ disMax . add ( new CombinedFieldsQueryBuilder ( value , group .getValue (). toArray ( new String [ 0 ])) );
324+ }
335325
336- query = Queries .maybeApplyMinimumShouldMatch (query , minimumShouldMatch );
337- if (query == null ) {
338- query = zeroTermsQuery .asQuery ();
339- }
340- queries .add (query );
326+ /*
327+ TODO
328+ Query query = disMax.createBooleanQuery(placeholderFieldName, value.toString(), operator.toBooleanClauseOccur());
329+ query = Queries.maybeApplyMinimumShouldMatch(query, minimumShouldMatch);
330+ if (query == null) {
331+ query = zeroTermsQuery.asQuery();
341332 }
342333
343- // TODO: combine queries.
344- return queries . getFirst ( );
334+ */
335+ return disMax . doToQuery ( context );
345336 }
346337
347338 private static void validateSimilarity (SearchExecutionContext context , Map <String , Float > fields ) {
@@ -359,89 +350,6 @@ private static void validateSimilarity(SearchExecutionContext context, Map<Strin
359350 }
360351 }
361352
362- private static final class FieldAndBoost {
363- final MappedFieldType fieldType ;
364- final float boost ;
365-
366- FieldAndBoost (MappedFieldType fieldType , float boost ) {
367- this .fieldType = Objects .requireNonNull (fieldType );
368- this .boost = boost ;
369- }
370- }
371-
372- private static class CombinedFieldsBuilder extends QueryBuilder {
373- private final List <FieldAndBoost > fields ;
374- private final SearchExecutionContext context ;
375-
376- CombinedFieldsBuilder (
377- List <FieldAndBoost > fields ,
378- Analyzer analyzer ,
379- boolean autoGenerateSynonymsPhraseQuery ,
380- SearchExecutionContext context
381- ) {
382- super (analyzer );
383- this .fields = fields ;
384- setAutoGenerateMultiTermSynonymsPhraseQuery (autoGenerateSynonymsPhraseQuery );
385- this .context = context ;
386- }
387-
388- @ Override
389- protected Query createFieldQuery (TokenStream source , BooleanClause .Occur operator , String field , boolean quoted , int phraseSlop ) {
390- if (source .hasAttribute (DisableGraphAttribute .class )) {
391- /*
392- * A {@link TokenFilter} in this {@link TokenStream} disabled the graph analysis to avoid
393- * paths explosion. See {@link org.elasticsearch.index.analysis.ShingleTokenFilterFactory} for details.
394- */
395- setEnableGraphQueries (false );
396- }
397- try {
398- return super .createFieldQuery (source , operator , field , quoted , phraseSlop );
399- } finally {
400- setEnableGraphQueries (true );
401- }
402- }
403-
404- @ Override
405- public Query createPhraseQuery (String field , String queryText , int phraseSlop ) {
406- throw new IllegalArgumentException ("[multi_field_match] queries don't support phrases" );
407- }
408-
409- @ Override
410- protected Query newSynonymQuery (String field , TermAndBoost [] terms ) {
411- CombinedFieldQuery .Builder query = new CombinedFieldQuery .Builder ();
412- for (TermAndBoost termAndBoost : terms ) {
413- assert termAndBoost .boost () == BoostAttribute .DEFAULT_BOOST ;
414- BytesRef bytes = termAndBoost .term ();
415- query .addTerm (bytes );
416- }
417- for (FieldAndBoost fieldAndBoost : fields ) {
418- MappedFieldType fieldType = fieldAndBoost .fieldType ;
419- float fieldBoost = fieldAndBoost .boost ;
420- query .addField (fieldType .name (), fieldBoost );
421- }
422- return query .build ();
423- }
424-
425- @ Override
426- protected Query newTermQuery (Term term , float boost ) {
427- TermAndBoost termAndBoost = new TermAndBoost (term .bytes (), boost );
428- return newSynonymQuery (term .field (), new TermAndBoost [] { termAndBoost });
429- }
430-
431- @ Override
432- protected Query analyzePhrase (String field , TokenStream stream , int slop ) throws IOException {
433- BooleanQuery .Builder builder = new BooleanQuery .Builder ();
434- for (FieldAndBoost fieldAndBoost : fields ) {
435- Query query = fieldAndBoost .fieldType .phraseQuery (stream , slop , enablePositionIncrements , context );
436- if (fieldAndBoost .boost != 1f ) {
437- query = new BoostQuery (query , fieldAndBoost .boost );
438- }
439- builder .add (query , BooleanClause .Occur .SHOULD );
440- }
441- return builder .build ();
442- }
443- }
444-
445353 @ Override
446354 protected int doHashCode () {
447355 return Objects .hash (value , fieldsAndBoosts , operator , minimumShouldMatch , zeroTermsQuery , autoGenerateSynonymsPhraseQuery );
0 commit comments