|
@@ -19,14 +19,12 @@
|
|
|
|
|
|
package org.elasticsearch.search.dfs;
|
|
|
|
|
|
-import com.carrotsearch.hppc.ObjectHashSet;
|
|
|
import com.carrotsearch.hppc.ObjectObjectHashMap;
|
|
|
-import com.carrotsearch.hppc.cursors.ObjectCursor;
|
|
|
-
|
|
|
-import org.apache.lucene.index.IndexReaderContext;
|
|
|
import org.apache.lucene.index.Term;
|
|
|
import org.apache.lucene.index.TermStates;
|
|
|
import org.apache.lucene.search.CollectionStatistics;
|
|
|
+import org.apache.lucene.search.IndexSearcher;
|
|
|
+import org.apache.lucene.search.Query;
|
|
|
import org.apache.lucene.search.ScoreMode;
|
|
|
import org.apache.lucene.search.TermStatistics;
|
|
|
import org.elasticsearch.common.collect.HppcMaps;
|
|
@@ -36,9 +34,8 @@ import org.elasticsearch.search.rescore.RescoreContext;
|
|
|
import org.elasticsearch.tasks.TaskCancelledException;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
-import java.util.AbstractSet;
|
|
|
-import java.util.Collection;
|
|
|
-import java.util.Iterator;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
/**
|
|
|
* Dfs phase of a search request, used to make scoring 100% accurate by collecting additional info from each shard before the query phase.
|
|
@@ -52,42 +49,46 @@ public class DfsPhase implements SearchPhase {
|
|
|
|
|
|
@Override
|
|
|
public void execute(SearchContext context) {
|
|
|
- final ObjectHashSet<Term> termsSet = new ObjectHashSet<>();
|
|
|
try {
|
|
|
- context.searcher().createWeight(context.searcher().rewrite(context.query()), ScoreMode.COMPLETE, 1f)
|
|
|
- .extractTerms(new DelegateSet(termsSet));
|
|
|
+ ObjectObjectHashMap<String, CollectionStatistics> fieldStatistics = HppcMaps.newNoNullKeysMap();
|
|
|
+ Map<Term, TermStatistics> stats = new HashMap<>();
|
|
|
+ IndexSearcher searcher = new IndexSearcher(context.searcher().getIndexReader()) {
|
|
|
+ @Override
|
|
|
+ public TermStatistics termStatistics(Term term, TermStates states) throws IOException {
|
|
|
+ if (context.isCancelled()) {
|
|
|
+ throw new TaskCancelledException("cancelled");
|
|
|
+ }
|
|
|
+ TermStatistics ts = super.termStatistics(term, states);
|
|
|
+ if (ts != null) {
|
|
|
+ stats.put(term, ts);
|
|
|
+ }
|
|
|
+ return ts;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public CollectionStatistics collectionStatistics(String field) throws IOException {
|
|
|
+ if (context.isCancelled()) {
|
|
|
+ throw new TaskCancelledException("cancelled");
|
|
|
+ }
|
|
|
+ CollectionStatistics cs = super.collectionStatistics(field);
|
|
|
+ if (cs != null) {
|
|
|
+ fieldStatistics.put(field, cs);
|
|
|
+ }
|
|
|
+ return cs;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ searcher.createWeight(context.searcher().rewrite(context.query()), ScoreMode.COMPLETE, 1);
|
|
|
for (RescoreContext rescoreContext : context.rescore()) {
|
|
|
- try {
|
|
|
- rescoreContext.rescorer().extractTerms(context.searcher(), rescoreContext, new DelegateSet(termsSet));
|
|
|
- } catch (IOException e) {
|
|
|
- throw new IllegalStateException("Failed to extract terms", e);
|
|
|
+ for (Query query : rescoreContext.getQueries()) {
|
|
|
+ searcher.createWeight(context.searcher().rewrite(query), ScoreMode.COMPLETE, 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- Term[] terms = termsSet.toArray(Term.class);
|
|
|
+ Term[] terms = stats.keySet().toArray(new Term[0]);
|
|
|
TermStatistics[] termStatistics = new TermStatistics[terms.length];
|
|
|
- IndexReaderContext indexReaderContext = context.searcher().getTopReaderContext();
|
|
|
for (int i = 0; i < terms.length; i++) {
|
|
|
- if(context.isCancelled()) {
|
|
|
- throw new TaskCancelledException("cancelled");
|
|
|
- }
|
|
|
- // LUCENE 4 UPGRADE: cache TermStates?
|
|
|
- TermStates termContext = TermStates.build(indexReaderContext, terms[i], true);
|
|
|
- termStatistics[i] = context.searcher().termStatistics(terms[i], termContext);
|
|
|
- }
|
|
|
-
|
|
|
- ObjectObjectHashMap<String, CollectionStatistics> fieldStatistics = HppcMaps.newNoNullKeysMap();
|
|
|
- for (Term term : terms) {
|
|
|
- assert term.field() != null : "field is null";
|
|
|
- if (fieldStatistics.containsKey(term.field()) == false) {
|
|
|
- final CollectionStatistics collectionStatistics = context.searcher().collectionStatistics(term.field());
|
|
|
- if (collectionStatistics != null) {
|
|
|
- fieldStatistics.put(term.field(), collectionStatistics);
|
|
|
- }
|
|
|
- if(context.isCancelled()) {
|
|
|
- throw new TaskCancelledException("cancelled");
|
|
|
- }
|
|
|
- }
|
|
|
+ termStatistics[i] = stats.get(terms[i]);
|
|
|
}
|
|
|
|
|
|
context.dfsResult().termsStatistics(terms, termStatistics)
|
|
@@ -95,58 +96,6 @@ public class DfsPhase implements SearchPhase {
|
|
|
.maxDoc(context.searcher().getIndexReader().maxDoc());
|
|
|
} catch (Exception e) {
|
|
|
throw new DfsPhaseExecutionException(context, "Exception during dfs phase", e);
|
|
|
- } finally {
|
|
|
- termsSet.clear(); // don't hold on to terms
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // We need to bridge to JCF world, b/c of Query#extractTerms
|
|
|
- private static class DelegateSet extends AbstractSet<Term> {
|
|
|
-
|
|
|
- private final ObjectHashSet<Term> delegate;
|
|
|
-
|
|
|
- private DelegateSet(ObjectHashSet<Term> delegate) {
|
|
|
- this.delegate = delegate;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean add(Term term) {
|
|
|
- return delegate.add(term);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean addAll(Collection<? extends Term> terms) {
|
|
|
- boolean result = false;
|
|
|
- for (Term term : terms) {
|
|
|
- result = delegate.add(term);
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Iterator<Term> iterator() {
|
|
|
- final Iterator<ObjectCursor<Term>> iterator = delegate.iterator();
|
|
|
- return new Iterator<Term>() {
|
|
|
- @Override
|
|
|
- public boolean hasNext() {
|
|
|
- return iterator.hasNext();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public Term next() {
|
|
|
- return iterator.next().value;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void remove() {
|
|
|
- throw new UnsupportedOperationException();
|
|
|
- }
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int size() {
|
|
|
- return delegate.size();
|
|
|
}
|
|
|
}
|
|
|
|