LUCENE_7747: QueryBuilder now iterates lazily over the possible paths when building a graph query
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index bb2658a..234eb64 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -150,6 +150,8 @@
* LUCENE-7695: ComplexPhraseQueryParser to support query time synonyms (Markus Jelsma
via Mikhail Khludnev)
+* LUCENE_7747: QueryBuilder now iterates lazily over the possible paths when building a graph query
+
Optimizations
* LUCENE-7641: Optimized point range queries to compute documents that do not
diff --git a/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java b/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java
index 286f673..fc5f97a 100644
--- a/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java
+++ b/lucene/core/src/java/org/apache/lucene/util/QueryBuilder.java
@@ -19,7 +19,6 @@
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
@@ -513,21 +512,20 @@
lastState = end;
final Query queryPos;
if (graph.hasSidePath(start)) {
- List<Query> queries = new ArrayList<> ();
- Iterator<TokenStream> it = graph.getFiniteStrings(start, end);
- while (it.hasNext()) {
- TokenStream ts = it.next();
- // This is a synonym path so all terms are mandatory (MUST).
- Query q = createFieldQuery(ts, BooleanClause.Occur.MUST, field, getAutoGenerateMultiTermSynonymsPhraseQuery(), 0);
- if (q != null) {
- queries.add(q);
+ final Iterator<TokenStream> it = graph.getFiniteStrings(start, end);
+ Iterator<Query> queries = new Iterator<Query>() {
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
}
- }
- if (queries.size() > 0) {
- queryPos = newGraphSynonymQuery(queries.toArray(new Query[queries.size()]));
- } else {
- queryPos = null;
- }
+
+ @Override
+ public Query next() {
+ TokenStream ts = it.next();
+ return createFieldQuery(ts, BooleanClause.Occur.MUST, field, getAutoGenerateMultiTermSynonymsPhraseQuery(), 0);
+ }
+ };
+ queryPos = newGraphSynonymQuery(queries);
} else {
Term[] terms = graph.getTerms(field, start);
assert terms.length > 0;
@@ -637,16 +635,16 @@
* This is intended for subclasses that wish to customize the generated queries.
* @return new Query instance
*/
- protected Query newGraphSynonymQuery(Query queries[]) {
- if (queries == null) {
- return new BooleanQuery.Builder().build();
- } else if (queries.length == 1) {
- return queries[0];
- } else {
- BooleanQuery.Builder builder = new BooleanQuery.Builder();
- Arrays.stream(queries).forEachOrdered(qry -> builder.add(qry, BooleanClause.Occur.SHOULD));
- return builder.build();
+ protected Query newGraphSynonymQuery(Iterator<Query> queries) {
+ BooleanQuery.Builder builder = new BooleanQuery.Builder();
+ while (queries.hasNext()) {
+ builder.add(queries.next(), BooleanClause.Occur.SHOULD);
}
+ BooleanQuery bq = builder.build();
+ if (bq.clauses().size() == 1) {
+ return bq.clauses().get(0).getQuery();
+ }
+ return bq;
}
/**