mirror of https://github.com/apache/lucene.git
SOLR-9704: optimization: use filters after blockChildren for acceptDocs
This commit is contained in:
parent
d8d3a8b9b8
commit
0f8802ba20
|
@ -86,6 +86,11 @@ New Features
|
||||||
Example: { type:terms, field:category, filter:"user:yonik" }
|
Example: { type:terms, field:category, filter:"user:yonik" }
|
||||||
(yonik)
|
(yonik)
|
||||||
|
|
||||||
|
Optimizations
|
||||||
|
----------------------
|
||||||
|
* SOLR-9704: Facet Module / JSON Facet API: Optimize blockChildren facets that have
|
||||||
|
filters specified by using those filters as acceptDocs. (yonik)
|
||||||
|
|
||||||
Other Changes
|
Other Changes
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ import java.util.Map;
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
import org.apache.lucene.search.BooleanClause;
|
import org.apache.lucene.search.BooleanClause;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||||
|
@ -88,14 +87,14 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
|
||||||
public void process() throws IOException {
|
public void process() throws IOException {
|
||||||
// Check filters... if we do have filters they apply after domain changes.
|
// Check filters... if we do have filters they apply after domain changes.
|
||||||
// We still calculate them first because we can use it in a parent->child domain change.
|
// We still calculate them first because we can use it in a parent->child domain change.
|
||||||
handleFilters();
|
evalFilters();
|
||||||
handleDomainChanges();
|
boolean appliedFilters = handleDomainChanges();
|
||||||
if (filter != null) {
|
if (filter != null && !appliedFilters) {
|
||||||
fcontext.base = fcontext.base.intersection( filter );
|
fcontext.base = fcontext.base.intersection( filter );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleFilters() throws IOException {
|
private void evalFilters() throws IOException {
|
||||||
if (freq.filters == null || freq.filters.isEmpty()) return;
|
if (freq.filters == null || freq.filters.isEmpty()) return;
|
||||||
|
|
||||||
List<Query> qlist = new ArrayList<>(freq.filters.size());
|
List<Query> qlist = new ArrayList<>(freq.filters.size());
|
||||||
|
@ -120,10 +119,11 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
|
||||||
this.filter = fcontext.searcher.getDocSet(qlist);
|
this.filter = fcontext.searcher.getDocSet(qlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleDomainChanges() throws IOException {
|
private boolean handleDomainChanges() throws IOException {
|
||||||
if (freq.domain == null) return;
|
if (freq.domain == null) return false;
|
||||||
handleFilterExclusions();
|
handleFilterExclusions();
|
||||||
handleBlockJoin();
|
boolean appliedFilters = handleBlockJoin();
|
||||||
|
return appliedFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleFilterExclusions() throws IOException {
|
private void handleFilterExclusions() throws IOException {
|
||||||
|
@ -187,8 +187,10 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
|
||||||
fcontext.base = fcontext.searcher.getDocSet(qlist);
|
fcontext.base = fcontext.searcher.getDocSet(qlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleBlockJoin() throws IOException {
|
// returns "true" if filters have already been applied.
|
||||||
if (!(freq.domain.toChildren || freq.domain.toParent)) return;
|
private boolean handleBlockJoin() throws IOException {
|
||||||
|
boolean appliedFilters = false;
|
||||||
|
if (!(freq.domain.toChildren || freq.domain.toParent)) return appliedFilters;
|
||||||
|
|
||||||
// TODO: avoid query parsing per-bucket somehow...
|
// TODO: avoid query parsing per-bucket somehow...
|
||||||
String parentStr = freq.domain.parents;
|
String parentStr = freq.domain.parents;
|
||||||
|
@ -205,13 +207,21 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
|
||||||
DocSet result;
|
DocSet result;
|
||||||
|
|
||||||
if (freq.domain.toChildren) {
|
if (freq.domain.toChildren) {
|
||||||
DocSet filt = fcontext.searcher.getDocSetBits( new MatchAllDocsQuery() );
|
// If there are filters on this facet, then use them as acceptDocs when executing toChildren.
|
||||||
result = BlockJoin.toChildren(input, parents, filt, fcontext.qcontext);
|
// We need to remember to not redundantly re-apply these filters after.
|
||||||
|
DocSet acceptDocs = this.filter;
|
||||||
|
if (acceptDocs == null) {
|
||||||
|
acceptDocs = fcontext.searcher.getLiveDocs();
|
||||||
|
} else {
|
||||||
|
appliedFilters = true;
|
||||||
|
}
|
||||||
|
result = BlockJoin.toChildren(input, parents, acceptDocs, fcontext.qcontext);
|
||||||
} else {
|
} else {
|
||||||
result = BlockJoin.toParents(input, parents, fcontext.qcontext);
|
result = BlockJoin.toParents(input, parents, fcontext.qcontext);
|
||||||
}
|
}
|
||||||
|
|
||||||
fcontext.base = result;
|
fcontext.base = result;
|
||||||
|
return appliedFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void processStats(SimpleOrderedMap<Object> bucket, DocSet docs, int docCount) throws IOException {
|
protected void processStats(SimpleOrderedMap<Object> bucket, DocSet docs, int docCount) throws IOException {
|
||||||
|
|
Loading…
Reference in New Issue