mappings: Search filter should wrap the types filters in a separate boolean as should clauses

So that a document must either match with one of the types and the non nested clause.

Closes #15757
This commit is contained in:
Martijn van Groningen 2016-01-12 12:10:58 +01:00
parent ce32b959fd
commit a2796b555f
2 changed files with 32 additions and 4 deletions

View File

@ -519,16 +519,17 @@ public class MapperService extends AbstractIndexComponent implements Closeable {
return termsFilter;
}
} else {
// Current bool filter requires that at least one should clause matches, even with a must clause.
BooleanQuery.Builder bool = new BooleanQuery.Builder();
BooleanQuery.Builder typesBool = new BooleanQuery.Builder();
for (String type : types) {
DocumentMapper docMapper = documentMapper(type);
if (docMapper == null) {
bool.add(new TermQuery(new Term(TypeFieldMapper.NAME, type)), BooleanClause.Occur.SHOULD);
typesBool.add(new TermQuery(new Term(TypeFieldMapper.NAME, type)), BooleanClause.Occur.SHOULD);
} else {
bool.add(docMapper.typeFilter(), BooleanClause.Occur.SHOULD);
typesBool.add(docMapper.typeFilter(), BooleanClause.Occur.SHOULD);
}
}
BooleanQuery.Builder bool = new BooleanQuery.Builder();
bool.add(typesBool.build(), Occur.MUST);
if (filterPercolateType) {
bool.add(percolatorType, BooleanClause.Occur.MUST_NOT);
}

View File

@ -19,9 +19,17 @@
package org.elasticsearch.index.mapper;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.internal.TypeFieldMapper;
import org.elasticsearch.test.ESSingleNodeTestCase;
import org.junit.Rule;
import org.junit.rules.ExpectedException;
@ -32,6 +40,7 @@ import java.util.HashSet;
import java.util.concurrent.ExecutionException;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasToString;
public class MapperServiceTests extends ESSingleNodeTestCase {
@ -122,4 +131,22 @@ public class MapperServiceTests extends ESSingleNodeTestCase {
}
assertFalse(indexService.mapperService().hasMapping(MapperService.DEFAULT_MAPPING));
}
public void testSearchFilter() {
IndexService indexService = createIndex("index1", client().admin().indices().prepareCreate("index1")
.addMapping("type1", "field1", "type=nested")
.addMapping("type2", new Object[0])
);
Query searchFilter = indexService.mapperService().searchFilter("type1", "type3");
Query expectedQuery = new BooleanQuery.Builder()
.add(new BooleanQuery.Builder()
.add(new ConstantScoreQuery(new TermQuery(new Term(TypeFieldMapper.NAME, "type1"))), BooleanClause.Occur.SHOULD)
.add(new TermQuery(new Term(TypeFieldMapper.NAME, "type3")), BooleanClause.Occur.SHOULD)
.build(), BooleanClause.Occur.MUST
)
.add(Queries.newNonNestedFilter(), BooleanClause.Occur.MUST)
.build();
assertThat(searchFilter, equalTo(new ConstantScoreQuery(expectedQuery)));
}
}