Improve performance when searching across multiple types, closes #478.

This commit is contained in:
kimchy 2010-11-04 20:34:49 +02:00
parent bbd63f0ffe
commit 99a3e615ab
4 changed files with 24 additions and 61 deletions

View File

@ -22,6 +22,9 @@ package org.elasticsearch.index.mapper;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.TermsFilter;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.UnmodifiableIterator;
import org.elasticsearch.common.inject.Inject;
@ -218,6 +221,20 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
return mappers.get(type);
}
/**
* A filter to filter based on several types.
*/
public Filter typesFilter(String... types) {
if (types.length == 1) {
return documentMapper(types[0]).typeFilter();
}
TermsFilter termsFilter = new TermsFilter();
for (String type : types) {
termsFilter.addTerm(new Term(TypeFieldMapper.NAME, type));
}
return termsFilter;
}
/**
* Returns {@link FieldMappers} for all the {@link FieldMapper}s that are registered
* under the given name across all the different {@link DocumentMapper} types.

View File

@ -23,8 +23,6 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.index.CheckIndex;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.FilterClause;
import org.apache.lucene.search.FilteredQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.ThreadInterruptedException;
@ -36,7 +34,6 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.io.FastByteArrayOutputStream;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.lucene.search.XBooleanFilter;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
@ -55,7 +52,6 @@ import org.elasticsearch.index.shard.*;
import org.elasticsearch.index.shard.recovery.RecoveryStatus;
import org.elasticsearch.index.store.Store;
import org.elasticsearch.index.translog.Translog;
import org.elasticsearch.indices.TypeMissingException;
import org.elasticsearch.threadpool.ThreadPool;
import javax.annotation.Nullable;
@ -532,24 +528,7 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
private Query filterByTypesIfNeeded(Query query, String[] types) {
if (types != null && types.length > 0) {
if (types.length == 1) {
String type = types[0];
DocumentMapper docMapper = mapperService.documentMapper(type);
if (docMapper == null) {
throw new TypeMissingException(shardId.index(), type);
}
query = new FilteredQuery(query, indexCache.filter().cache(docMapper.typeFilter()));
} else {
XBooleanFilter booleanFilter = new XBooleanFilter();
for (String type : types) {
DocumentMapper docMapper = mapperService.documentMapper(type);
if (docMapper == null) {
throw new TypeMissingException(shardId.index(), type);
}
booleanFilter.add(new FilterClause(indexCache.filter().cache(docMapper.typeFilter()), BooleanClause.Occur.SHOULD));
}
query = new FilteredQuery(query, booleanFilter);
}
query = new FilteredQuery(query, indexCache.filter().cache(mapperService.typesFilter(types)));
}
return query;
}

View File

@ -19,8 +19,6 @@
package org.elasticsearch.search.facet;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.FilterClause;
import org.apache.lucene.search.FilteredQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticSearchException;
@ -28,8 +26,6 @@ import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.Lists;
import org.elasticsearch.common.lucene.search.NoopCollector;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.lucene.search.XBooleanFilter;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.SearchPhase;
import org.elasticsearch.search.facet.collector.FacetCollector;
@ -66,18 +62,7 @@ public class FacetsPhase implements SearchPhase {
if (context.searcher().globalCollectors() != null) {
Query query = Queries.MATCH_ALL_QUERY;
if (context.types().length > 0) {
if (context.types().length == 1) {
String type = context.types()[0];
DocumentMapper docMapper = context.mapperService().documentMapper(type);
query = new FilteredQuery(query, context.filterCache().cache(docMapper.typeFilter()));
} else {
XBooleanFilter booleanFilter = new XBooleanFilter();
for (String type : context.types()) {
DocumentMapper docMapper = context.mapperService().documentMapper(type);
booleanFilter.add(new FilterClause(context.filterCache().cache(docMapper.typeFilter()), BooleanClause.Occur.SHOULD));
}
query = new FilteredQuery(query, booleanFilter);
}
query = new FilteredQuery(query, context.filterCache().cache(context.mapperService().typesFilter(context.types())));
}
context.searcher().useGlobalCollectors(true);

View File

@ -19,16 +19,15 @@
package org.elasticsearch.search.query;
import org.apache.lucene.search.*;
import org.apache.lucene.search.FilteredQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.search.XBooleanFilter;
import org.elasticsearch.common.lucene.search.function.BoostScoreFunction;
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.query.ParsedQuery;
import org.elasticsearch.indices.TypeMissingException;
import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.SearchParseException;
import org.elasticsearch.search.SearchPhase;
@ -81,24 +80,7 @@ public class QueryPhase implements SearchPhase {
Query query = searchContext.query();
if (searchContext.types().length > 0) {
if (searchContext.types().length == 1) {
String type = searchContext.types()[0];
DocumentMapper docMapper = searchContext.mapperService().documentMapper(type);
if (docMapper == null) {
throw new TypeMissingException(new Index(searchContext.shardTarget().index()), type);
}
query = new FilteredQuery(query, searchContext.filterCache().cache(docMapper.typeFilter()));
} else {
XBooleanFilter booleanFilter = new XBooleanFilter();
for (String type : searchContext.types()) {
DocumentMapper docMapper = searchContext.mapperService().documentMapper(type);
if (docMapper == null) {
throw new TypeMissingException(new Index(searchContext.shardTarget().index()), type);
}
booleanFilter.add(new FilterClause(searchContext.filterCache().cache(docMapper.typeFilter()), BooleanClause.Occur.SHOULD));
}
query = new FilteredQuery(query, booleanFilter);
}
query = new FilteredQuery(query, searchContext.filterCache().cache(searchContext.mapperService().typesFilter(searchContext.types())));
}
TopDocs topDocs;