Skip to content

Commit daa25d1

Browse files
committed
Merge pull request #10531 from jpountz/upgrade/lucene-5.1-queries
Search: Replace deprecated filters with equivalent queries.
2 parents b31e590 + d7abb12 commit daa25d1

File tree

129 files changed

+925
-4103
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+925
-4103
lines changed

dev-tools/forbidden/all-signatures.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ java.nio.file.Path#toFile()
3333
@defaultMessage Don't use deprecated lucene apis
3434
org.apache.lucene.index.DocsEnum
3535
org.apache.lucene.index.DocsAndPositionsEnum
36+
org.apache.lucene.queries.TermFilter
37+
org.apache.lucene.queries.TermsFilter
38+
org.apache.lucene.search.TermRangeFilter
39+
org.apache.lucene.search.NumericRangeFilter
40+
org.apache.lucene.search.PrefixFilter
3641

3742
java.nio.file.Paths @ Use PathUtils.get instead.
3843
java.nio.file.FileSystems#getDefault() @ use PathUtils.getDefault instead.

docs/reference/migration/migrate_2_0.asciidoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,18 @@ http.cors.allow-origin: /https?:\/\/localhost(:[0-9]+)?/
374374
The cluster state api doesn't return the `routing_nodes` section anymore when
375375
`routing_table` is requested. The newly introduced `routing_nodes` flag can
376376
be used separately to control whether `routing_nodes` should be returned.
377+
377378
=== Query DSL
378379

379380
The `fuzzy_like_this` and `fuzzy_like_this_field` queries have been removed.
380381

381382
The `limit` filter is deprecated and becomes a no-op. You can achieve similar
382383
behaviour using the <<search-request-body,terminate_after>> parameter.
384+
385+
`or` and `and` on the one hand and `bool` on the other hand used to have
386+
different performance characteristics depending on the wrapped filters. This is
387+
fixed now, as a consequence the `or` and `and` filters are now deprecated in
388+
favour or `bool`.
389+
390+
The `execution` option of the `terms` filter is now deprecated and ignored if
391+
provided.

docs/reference/query-dsl/filters/and-filter.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[[query-dsl-and-filter]]
22
=== And Filter
33

4+
deprecated[2.0.0, Use the `bool` filter instead]
5+
46
A filter that matches documents using the `AND` boolean operator on other
57
filters. Can be placed within queries that accept a filter.
68

docs/reference/query-dsl/filters/or-filter.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
[[query-dsl-or-filter]]
22
=== Or Filter
33

4+
deprecated[2.0.0, Use the `bool` filter instead]
5+
46
A filter that matches documents using the `OR` boolean operator on other
57
filters. Can be placed within queries that accept a filter.
68

docs/reference/query-dsl/filters/terms-filter.asciidoc

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -18,71 +18,6 @@ Filters documents that have fields that match any of the provided terms
1818
The `terms` filter is also aliased with `in` as the filter name for
1919
simpler usage.
2020

21-
[float]
22-
==== Execution Mode
23-
24-
The way terms filter executes is by iterating over the terms provided
25-
and finding matches docs (loading into a bitset) and caching it.
26-
Sometimes, we want a different execution model that can still be
27-
achieved by building more complex queries in the DSL, but we can support
28-
them in the more compact model that terms filter provides.
29-
30-
The `execution` option now has the following options :
31-
32-
[horizontal]
33-
`plain`::
34-
The default. Works as today. Iterates over all the terms,
35-
building a bit set matching it, and filtering. The total filter is
36-
cached.
37-
38-
`fielddata`::
39-
Generates a terms filters that uses the fielddata cache to
40-
compare terms. This execution mode is great to use when filtering
41-
on a field that is already loaded into the fielddata cache from
42-
aggregating, sorting, or index warmers. When filtering on
43-
a large number of terms, this execution can be considerably faster
44-
than the other modes. The total filter is not cached unless
45-
explicitly configured to do so.
46-
47-
`bool`::
48-
Generates a term filter (which is cached) for each term, and
49-
wraps those in a bool filter. The bool filter itself is not cached as it
50-
can operate very quickly on the cached term filters.
51-
52-
`and`::
53-
Generates a term filter (which is cached) for each term, and
54-
wraps those in an and filter. The and filter itself is not cached.
55-
56-
`or`::
57-
Generates a term filter (which is cached) for each term, and
58-
wraps those in an or filter. The or filter itself is not cached.
59-
Generally, the `bool` execution mode should be preferred.
60-
61-
If you don't want the generated individual term queries to be cached,
62-
you can use: `bool_nocache`, `and_nocache` or `or_nocache` instead, but
63-
be aware that this will affect performance.
64-
65-
The "total" terms filter caching can still be explicitly controlled
66-
using the `_cache` option. Note the default value for it depends on the
67-
execution value.
68-
69-
For example:
70-
71-
[source,js]
72-
--------------------------------------------------
73-
{
74-
"constant_score" : {
75-
"filter" : {
76-
"terms" : {
77-
"user" : ["kimchy", "elasticsearch"],
78-
"execution" : "bool",
79-
"_cache": true
80-
}
81-
}
82-
}
83-
}
84-
--------------------------------------------------
85-
8621
[float]
8722
==== Caching
8823

rest-api-spec/test/indices.validate_query/10_basic.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
- is_true: valid
3333
- match: {_shards.failed: 0}
3434
- match: {explanations.0.index: 'testing'}
35-
- match: {explanations.0.explanation: 'ConstantScore(*:*)'}
35+
- match: {explanations.0.explanation: '*:*'}
3636

src/main/java/org/apache/lucene/search/vectorhighlight/CustomFieldQuery.java

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,45 +22,30 @@
2222
import org.apache.lucene.index.IndexReader;
2323
import org.apache.lucene.index.Term;
2424
import org.apache.lucene.queries.BlendedTermQuery;
25-
import org.apache.lucene.queries.FilterClause;
26-
import org.apache.lucene.queries.TermFilter;
27-
import org.apache.lucene.search.BooleanClause;
2825
import org.apache.lucene.search.ConstantScoreQuery;
2926
import org.apache.lucene.search.Filter;
3027
import org.apache.lucene.search.FilteredQuery;
3128
import org.apache.lucene.search.MultiPhraseQuery;
32-
import org.apache.lucene.search.MultiTermQueryWrapperFilter;
3329
import org.apache.lucene.search.PhraseQuery;
3430
import org.apache.lucene.search.Query;
31+
import org.apache.lucene.search.QueryWrapperFilter;
3532
import org.apache.lucene.search.TermQuery;
3633
import org.apache.lucene.search.spans.SpanTermQuery;
3734
import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery;
38-
import org.elasticsearch.common.lucene.search.XBooleanFilter;
3935
import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery;
4036
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
4137

4238
import java.io.IOException;
43-
import java.lang.reflect.Field;
4439
import java.util.Collection;
4540
import java.util.List;
4641

4742
/**
4843
*
4944
*/
5045
// LUCENE MONITOR
46+
// TODO: remove me!
5147
public class CustomFieldQuery extends FieldQuery {
5248

53-
private static Field multiTermQueryWrapperFilterQueryField;
54-
55-
static {
56-
try {
57-
multiTermQueryWrapperFilterQueryField = MultiTermQueryWrapperFilter.class.getDeclaredField("query");
58-
multiTermQueryWrapperFilterQueryField.setAccessible(true);
59-
} catch (NoSuchFieldException e) {
60-
// ignore
61-
}
62-
}
63-
6449
public static final ThreadLocal<Boolean> highlightFilters = new ThreadLocal<>();
6550

6651
public CustomFieldQuery(Query query, IndexReader reader, FastVectorHighlighter highlighter) throws IOException {
@@ -140,25 +125,8 @@ void flatten(Filter sourceFilter, IndexReader reader, Collection<Query> flatQuer
140125
if (highlight == null || highlight.equals(Boolean.FALSE)) {
141126
return;
142127
}
143-
if (sourceFilter instanceof TermFilter) {
144-
// TermFilter is just a deprecated wrapper over QWF
145-
TermQuery actualQuery = (TermQuery) ((TermFilter) sourceFilter).getQuery();
146-
flatten(new TermQuery(actualQuery.getTerm()), reader, flatQueries);
147-
} else if (sourceFilter instanceof MultiTermQueryWrapperFilter) {
148-
if (multiTermQueryWrapperFilterQueryField != null) {
149-
try {
150-
flatten((Query) multiTermQueryWrapperFilterQueryField.get(sourceFilter), reader, flatQueries);
151-
} catch (IllegalAccessException e) {
152-
// ignore
153-
}
154-
}
155-
} else if (sourceFilter instanceof XBooleanFilter) {
156-
XBooleanFilter booleanFilter = (XBooleanFilter) sourceFilter;
157-
for (FilterClause clause : booleanFilter.clauses()) {
158-
if (clause.getOccur() == BooleanClause.Occur.MUST || clause.getOccur() == BooleanClause.Occur.SHOULD) {
159-
flatten(clause.getFilter(), reader, flatQueries);
160-
}
161-
}
128+
if (sourceFilter instanceof QueryWrapperFilter) {
129+
flatten(((QueryWrapperFilter) sourceFilter).getQuery(), reader, flatQueries);
162130
}
163131
}
164132
}

src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import org.elasticsearch.cluster.routing.GroupShardsIterator;
3838
import org.elasticsearch.cluster.routing.ShardRouting;
3939
import org.elasticsearch.common.inject.Inject;
40-
import org.elasticsearch.common.lucene.search.MatchNoDocsFilter;
4140
import org.elasticsearch.common.settings.Settings;
4241
import org.elasticsearch.common.util.BigArrays;
4342
import org.elasticsearch.index.IndexService;
@@ -219,7 +218,7 @@ protected ShardValidateQueryResponse shardOperation(ShardValidateQueryRequest re
219218

220219
private String getRewrittenQuery(IndexSearcher searcher, Query query) throws IOException {
221220
Query queryRewrite = searcher.rewrite(query);
222-
if (queryRewrite instanceof MatchNoDocsQuery || queryRewrite instanceof MatchNoDocsFilter) {
221+
if (queryRewrite instanceof MatchNoDocsQuery) {
223222
return query.toString();
224223
} else {
225224
return queryRewrite.toString();

src/main/java/org/elasticsearch/common/lucene/docset/AndDocIdSet.java

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,18 @@
1919

2020
package org.elasticsearch.common.lucene.docset;
2121

22-
import com.google.common.collect.Iterables;
23-
2422
import org.apache.lucene.search.DocIdSet;
2523
import org.apache.lucene.search.DocIdSetIterator;
2624
import org.apache.lucene.util.ArrayUtil;
25+
import org.apache.lucene.util.BitSet;
2726
import org.apache.lucene.util.Bits;
2827
import org.apache.lucene.util.InPlaceMergeSorter;
2928
import org.apache.lucene.util.RamUsageEstimator;
30-
import org.elasticsearch.common.lucene.search.XDocIdSetIterator;
3129

3230
import java.io.IOException;
3331
import java.util.ArrayList;
3432
import java.util.Arrays;
3533
import java.util.Collection;
36-
import java.util.Collections;
3734
import java.util.List;
3835

3936
/**
@@ -93,7 +90,7 @@ public DocIdSetIterator iterator() throws IOException {
9390
return DocIdSetIterator.empty();
9491
}
9592
Bits bit = set.bits();
96-
if (bit != null && DocIdSets.isBroken(it)) {
93+
if (bit != null && bit instanceof BitSet == false) {
9794
bits.add(bit);
9895
} else {
9996
iterators.add(it);
@@ -138,7 +135,7 @@ public int length() {
138135
}
139136
}
140137

141-
static class IteratorBasedIterator extends XDocIdSetIterator {
138+
static class IteratorBasedIterator extends DocIdSetIterator {
142139
private int doc = -1;
143140
private final DocIdSetIterator lead;
144141
private final DocIdSetIterator[] otherIterators;
@@ -174,16 +171,6 @@ protected void swap(int i, int j) {
174171
this.otherIterators = Arrays.copyOfRange(sortedIterators, 1, sortedIterators.length);
175172
}
176173

177-
@Override
178-
public boolean isBroken() {
179-
for (DocIdSetIterator it : Iterables.concat(Collections.singleton(lead), Arrays.asList(otherIterators))) {
180-
if (DocIdSets.isBroken(it)) {
181-
return true;
182-
}
183-
}
184-
return false;
185-
}
186-
187174
@Override
188175
public final int docID() {
189176
return doc;

src/main/java/org/elasticsearch/common/lucene/docset/DocIdSets.java

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
import org.apache.lucene.index.LeafReader;
2323
import org.apache.lucene.search.DocIdSet;
2424
import org.apache.lucene.search.DocIdSetIterator;
25-
import org.apache.lucene.search.DocValuesDocIdSet;
26-
import org.apache.lucene.search.FilteredDocIdSetIterator;
2725
import org.apache.lucene.util.BitDocIdSet;
2826
import org.apache.lucene.util.BitSet;
2927
import org.apache.lucene.util.Bits;
@@ -33,7 +31,6 @@
3331
import org.elasticsearch.ElasticsearchIllegalArgumentException;
3432
import org.elasticsearch.ElasticsearchIllegalStateException;
3533
import org.elasticsearch.common.Nullable;
36-
import org.elasticsearch.common.lucene.search.XDocIdSetIterator;
3734

3835
import java.io.IOException;
3936

@@ -55,31 +52,6 @@ public static boolean isEmpty(@Nullable DocIdSet set) {
5552
return set == null || set == DocIdSet.EMPTY;
5653
}
5754

58-
/**
59-
* Check if the given iterator can nextDoc() or advance() in sub-linear time
60-
* of the number of documents. For instance, an iterator that would need to
61-
* iterate one document at a time to check for its value would be considered
62-
* broken.
63-
*/
64-
public static boolean isBroken(DocIdSetIterator iterator) {
65-
while (iterator instanceof FilteredDocIdSetIterator) {
66-
// this iterator is filtered (likely by some bits)
67-
// unwrap in order to check if the underlying iterator is fast
68-
iterator = ((FilteredDocIdSetIterator) iterator).getDelegate();
69-
}
70-
if (iterator instanceof XDocIdSetIterator) {
71-
return ((XDocIdSetIterator) iterator).isBroken();
72-
}
73-
if (iterator instanceof MatchDocIdSetIterator) {
74-
return true;
75-
}
76-
// DocValuesDocIdSet produces anonymous slow iterators
77-
if (iterator != null && DocValuesDocIdSet.class.equals(iterator.getClass().getEnclosingClass())) {
78-
return true;
79-
}
80-
return false;
81-
}
82-
8355
/**
8456
* Converts to a cacheable {@link DocIdSet}
8557
* <p/>

0 commit comments

Comments
 (0)