diff --git a/changelog/unreleased/solr-12074-point-field-terms.yml b/changelog/unreleased/solr-12074-point-field-terms.yml new file mode 100644 index 00000000000..603b6da6db7 --- /dev/null +++ b/changelog/unreleased/solr-12074-point-field-terms.yml @@ -0,0 +1,10 @@ +# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc +title: Add option to index Point field terms, to speed up term lookup and close funcitonality gap with Trie fields +type: other # added, changed, fixed, deprecated, removed, dependency_update, security, other +authors: + - name: Houston Putman + nick: HoustonPutman + url: https://home.apache.org/phonebook.html?uid=houston +links: + - name: SOLR-12074 + url: https://issues.apache.org/jira/browse/SOLR-12074 diff --git a/solr/benchmark/src/java/org/apache/solr/bench/search/NumericSearch.java b/solr/benchmark/src/java/org/apache/solr/bench/search/NumericSearch.java index e7f574cd341..c9b3c3e5b20 100644 --- a/solr/benchmark/src/java/org/apache/solr/bench/search/NumericSearch.java +++ b/solr/benchmark/src/java/org/apache/solr/bench/search/NumericSearch.java @@ -147,20 +147,24 @@ public void setupIteration(MiniClusterState.MiniClusterBenchState miniClusterSta miniClusterState.client.requestWithBaseUrl(miniClusterState.nodes.get(0), reload, null); } - public QueryRequest intSetQuery(boolean dvs) { - return setQuery("numbers_i" + (dvs ? "_dv" : "")); + public QueryRequest intTrieSetQuery(boolean dvs, boolean enhancedIndex) { + return setQuery("numbers_it" + (dvs ? "_dv" : "")); } - public QueryRequest longSetQuery(boolean dvs) { - return setQuery("numbers_l" + (dvs ? "_dv" : "")); + public QueryRequest intSetQuery(boolean dvs, boolean enhancedIndex) { + return setQuery("numbers_i" + (dvs ? "_dv" : "") + (enhancedIndex ? "_e" : "")); } - public QueryRequest doubleSetQuery(boolean dvs) { - return setQuery("numbers_d" + (dvs ? "_dv" : "")); + public QueryRequest longSetQuery(boolean dvs, boolean enhancedIndex) { + return setQuery("numbers_l" + (dvs ? "_dv" : "") + (enhancedIndex ? "_e" : "")); } - public QueryRequest floatSetQuery(boolean dvs) { - return setQuery("numbers_f" + (dvs ? "_dv" : "")); + public QueryRequest doubleSetQuery(boolean dvs, boolean enhancedIndex) { + return setQuery("numbers_d" + (dvs ? "_dv" : "") + (enhancedIndex ? "_e" : "")); + } + + public QueryRequest floatSetQuery(boolean dvs, boolean enhancedIndex) { + return setQuery("numbers_f" + (dvs ? "_dv" : "") + (enhancedIndex ? "_e" : "")); } QueryRequest setQuery(String field) { @@ -175,6 +179,30 @@ QueryRequest setQuery(String field) { } } + @Benchmark + public Object intTrieSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.intTrieSetQuery(false, false).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object intTrieDvSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.intTrieSetQuery(false, false).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + @Benchmark public Object intSet( Blackhole blackhole, @@ -182,7 +210,7 @@ public Object intSet( MiniClusterState.MiniClusterBenchState miniClusterState) throws SolrServerException, IOException { QueryResponse response = - benchState.intSetQuery(false).process(miniClusterState.client, COLLECTION); + benchState.intSetQuery(false, false).process(miniClusterState.client, COLLECTION); blackhole.consume(response); return response; } @@ -194,7 +222,7 @@ public Object longSet( MiniClusterState.MiniClusterBenchState miniClusterState) throws SolrServerException, IOException { QueryResponse response = - benchState.longSetQuery(false).process(miniClusterState.client, COLLECTION); + benchState.longSetQuery(false, false).process(miniClusterState.client, COLLECTION); blackhole.consume(response); return response; } @@ -206,7 +234,7 @@ public Object floatSet( MiniClusterState.MiniClusterBenchState miniClusterState) throws SolrServerException, IOException { QueryResponse response = - benchState.floatSetQuery(false).process(miniClusterState.client, COLLECTION); + benchState.floatSetQuery(false, false).process(miniClusterState.client, COLLECTION); blackhole.consume(response); return response; } @@ -218,7 +246,7 @@ public Object doubleSet( MiniClusterState.MiniClusterBenchState miniClusterState) throws SolrServerException, IOException { QueryResponse response = - benchState.doubleSetQuery(false).process(miniClusterState.client, COLLECTION); + benchState.doubleSetQuery(false, false).process(miniClusterState.client, COLLECTION); blackhole.consume(response); return response; } @@ -230,7 +258,7 @@ public Object intDvSet( MiniClusterState.MiniClusterBenchState miniClusterState) throws SolrServerException, IOException { QueryResponse response = - benchState.intSetQuery(true).process(miniClusterState.client, COLLECTION); + benchState.intSetQuery(true, false).process(miniClusterState.client, COLLECTION); blackhole.consume(response); return response; } @@ -242,7 +270,7 @@ public Object longDvSet( MiniClusterState.MiniClusterBenchState miniClusterState) throws SolrServerException, IOException { QueryResponse response = - benchState.longSetQuery(true).process(miniClusterState.client, COLLECTION); + benchState.longSetQuery(true, false).process(miniClusterState.client, COLLECTION); blackhole.consume(response); return response; } @@ -254,7 +282,7 @@ public Object floatDvSet( MiniClusterState.MiniClusterBenchState miniClusterState) throws SolrServerException, IOException { QueryResponse response = - benchState.floatSetQuery(true).process(miniClusterState.client, COLLECTION); + benchState.floatSetQuery(true, false).process(miniClusterState.client, COLLECTION); blackhole.consume(response); return response; } @@ -266,7 +294,103 @@ public Object doubleDvSet( MiniClusterState.MiniClusterBenchState miniClusterState) throws SolrServerException, IOException { QueryResponse response = - benchState.doubleSetQuery(true).process(miniClusterState.client, COLLECTION); + benchState.doubleSetQuery(true, false).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object intEnhancedSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.intSetQuery(false, true).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object longEnhancedSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.longSetQuery(false, true).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object floatEnhancedSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.floatSetQuery(false, true).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object doubleEnhancedSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.doubleSetQuery(false, true).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object intDvEnhancedSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.intSetQuery(true, true).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object longDvEnhancedSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.longSetQuery(true, true).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object floatDvEnhancedSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.floatSetQuery(true, true).process(miniClusterState.client, COLLECTION); + blackhole.consume(response); + return response; + } + + @Benchmark + public Object doubleDvEnhancedSet( + Blackhole blackhole, + BenchState benchState, + MiniClusterState.MiniClusterBenchState miniClusterState) + throws SolrServerException, IOException { + QueryResponse response = + benchState.doubleSetQuery(true, true).process(miniClusterState.client, COLLECTION); blackhole.consume(response); return response; } diff --git a/solr/benchmark/src/resources/configs/cloud-minimal/conf/schema.xml b/solr/benchmark/src/resources/configs/cloud-minimal/conf/schema.xml index e517aea5930..4a2e440aef6 100644 --- a/solr/benchmark/src/resources/configs/cloud-minimal/conf/schema.xml +++ b/solr/benchmark/src/resources/configs/cloud-minimal/conf/schema.xml @@ -15,11 +15,13 @@ See the License for the specific language governing permissions and limitations under the License. --> - + + positionIncrementGap="0"/> + + + + + + + + + + + + + id diff --git a/solr/core/src/java/org/apache/solr/schema/DatePointField.java b/solr/core/src/java/org/apache/solr/schema/DatePointField.java index 83e3ac91699..6a253624544 100644 --- a/solr/core/src/java/org/apache/solr/schema/DatePointField.java +++ b/solr/core/src/java/org/apache/solr/schema/DatePointField.java @@ -22,8 +22,8 @@ import java.util.Collection; import java.util.Date; import java.util.Map; -import org.apache.lucene.document.LongField; import org.apache.lucene.document.LongPoint; +import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.document.StoredField; import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.LeafReaderContext; @@ -33,6 +33,7 @@ import org.apache.lucene.queries.function.docvalues.LongDocValues; import org.apache.lucene.queries.function.valuesource.LongFieldSource; import org.apache.lucene.queries.function.valuesource.MultiValuedLongFieldSource; +import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortedNumericSelector; @@ -157,28 +158,41 @@ public Object toObject(IndexableField f) { } } - @Override - protected Query getExactQuery(SchemaField field, String externalVal) { - return LongPoint.newExactQuery( - field.getName(), DateMathParser.parseMath(null, externalVal).getTime()); - } - @Override public Query getSetQuery(QParser parser, SchemaField field, Collection externalVals) { assert externalVals.size() > 0; - if (!field.indexed()) { - return super.getSetQuery(parser, field, externalVals); - } - long[] values = new long[externalVals.size()]; - int i = 0; - for (String val : externalVals) { - values[i] = DateMathParser.parseMath(null, val).getTime(); - i++; + Query indexQuery = null; + long[] values = null; + if (hasIndexedTerms(field)) { + indexQuery = super.getSetQuery(parser, field, externalVals); + } else if (field.indexed()) { + values = new long[externalVals.size()]; + int i = 0; + for (String val : externalVals) { + values[i++] = DateMathParser.parseMath(null, val).getTime(); + } + indexQuery = LongPoint.newSetQuery(field.getName(), values); } if (field.hasDocValues()) { - return LongField.newSetQuery(field.getName(), values); + long[] points = new long[externalVals.size()]; + if (values != null) { + points = values.clone(); + } else { + int i = 0; + for (String val : externalVals) { + points[i++] = DateMathParser.parseMath(null, val).getTime(); + } + } + Query docValuesQuery = SortedNumericDocValuesField.newSlowSetQuery(field.getName(), points); + if (indexQuery != null) { + return new IndexOrDocValuesQuery(indexQuery, docValuesQuery); + } else { + return docValuesQuery; + } + } else if (indexQuery != null) { + return indexQuery; } else { - return LongPoint.newSetQuery(field.getName(), values); + return super.getSetQuery(parser, field, externalVals); } } diff --git a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java index 430d3ff968d..7f4ea372250 100644 --- a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java +++ b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java @@ -18,14 +18,15 @@ package org.apache.solr.schema; import java.util.Collection; -import org.apache.lucene.document.DoubleField; import org.apache.lucene.document.DoublePoint; +import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.document.StoredField; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.IndexableField; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.queries.function.valuesource.DoubleFieldSource; import org.apache.lucene.queries.function.valuesource.MultiValuedDoubleFieldSource; +import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortedNumericSelector; @@ -109,27 +110,55 @@ public Object toObject(IndexableField f) { } @Override - protected Query getExactQuery(SchemaField field, String externalVal) { - return DoublePoint.newExactQuery( - field.getName(), parseDoubleFromUser(field.getName(), externalVal)); - } - - @Override - public Query getSetQuery(QParser parser, SchemaField field, Collection externalVal) { - assert externalVal.size() > 0; - if (!field.indexed()) { - return super.getSetQuery(parser, field, externalVal); - } - double[] values = new double[externalVal.size()]; - int i = 0; - for (String val : externalVal) { - values[i] = parseDoubleFromUser(field.getName(), val); - i++; + public Query getSetQuery(QParser parser, SchemaField field, Collection externalVals) { + assert externalVals.size() > 0; + Query indexQuery = null; + double[] values = null; + if (hasIndexedTerms(field)) { + indexQuery = super.getSetQuery(parser, field, externalVals); + } else if (field.indexed()) { + values = new double[externalVals.size()]; + int i = 0; + for (String val : externalVals) { + values[i++] = parseDoubleFromUser(field.getName(), val); + } + indexQuery = DoublePoint.newSetQuery(field.getName(), values); } if (field.hasDocValues()) { - return DoubleField.newSetQuery(field.getName(), values); + long[] points = new long[externalVals.size()]; + if (values != null) { + if (field.multiValued()) { + for (int i = 0; i < values.length; i++) { + points[i] = NumericUtils.doubleToSortableLong(values[i]); + } + } else { + for (int i = 0; i < values.length; i++) { + points[i] = Double.doubleToLongBits(values[i]); + } + } + } else { + int i = 0; + if (field.multiValued()) { + for (String val : externalVals) { + points[i++] = + NumericUtils.doubleToSortableLong(parseDoubleFromUser(field.getName(), val)); + } + } else { + for (String val : externalVals) { + points[i++] = Double.doubleToLongBits(parseDoubleFromUser(field.getName(), val)); + } + } + } + Query docValuesQuery = SortedNumericDocValuesField.newSlowSetQuery(field.getName(), points); + if (indexQuery != null) { + return new IndexOrDocValuesQuery(indexQuery, docValuesQuery); + } else { + return docValuesQuery; + } + } else if (indexQuery != null) { + return indexQuery; } else { - return DoublePoint.newSetQuery(field.getName(), values); + return super.getSetQuery(parser, field, externalVals); } } diff --git a/solr/core/src/java/org/apache/solr/schema/FieldProperties.java b/solr/core/src/java/org/apache/solr/schema/FieldProperties.java index 91f3caa38e6..f1693e4beba 100644 --- a/solr/core/src/java/org/apache/solr/schema/FieldProperties.java +++ b/solr/core/src/java/org/apache/solr/schema/FieldProperties.java @@ -53,6 +53,8 @@ public abstract class FieldProperties { protected static final int LARGE_FIELD = 0b1000000000000000000; protected static final int UNINVERTIBLE = 0b10000000000000000000; + protected static final int ENHANCED_INDEX = 0b100000000000000000000; + static final String[] propertyNames = { "indexed", "tokenized", @@ -73,7 +75,8 @@ public abstract class FieldProperties { "termPayloads", "useDocValuesAsStored", "large", - "uninvertible" + "uninvertible", + "enhancedIndex" }; static final Map propertyMap = new HashMap<>(); diff --git a/solr/core/src/java/org/apache/solr/schema/FieldType.java b/solr/core/src/java/org/apache/solr/schema/FieldType.java index 2f922473e50..6a0869cfc27 100644 --- a/solr/core/src/java/org/apache/solr/schema/FieldType.java +++ b/solr/core/src/java/org/apache/solr/schema/FieldType.java @@ -397,6 +397,11 @@ public Object toObject(SchemaField sf, BytesRef term) { return toObject(f); } + /** Return whether the given field can use Term queries */ + protected boolean hasIndexedTerms(SchemaField field) { + return field.indexed(); + } + /** Given an indexed term, return the human readable representation */ public String indexedToReadable(String indexedForm) { return indexedForm; @@ -1066,7 +1071,7 @@ protected Query getSpecializedExistenceQuery(QParser parser, SchemaField field) * {@link org.apache.lucene.search.TermQuery} but overriding queries may not */ public Query getFieldQuery(QParser parser, SchemaField field, String externalVal) { - if (field.hasDocValues() && !field.indexed()) { + if (field.hasDocValues() && !hasIndexedTerms(field)) { // match-only return getRangeQuery(parser, field, externalVal, externalVal, true, true); } else { @@ -1093,8 +1098,8 @@ public Query getFieldTermQuery(QParser parser, SchemaField field, String externa * @lucene.experimental */ public Query getSetQuery(QParser parser, SchemaField field, Collection externalVals) { - if (!field.indexed()) { - // TODO: if the field isn't indexed, this feels like the wrong query type to use? + if (!hasIndexedTerms(field)) { + // TODO: if the field doesn't have terms indexed, this feels like the wrong query type to use? BooleanQuery.Builder builder = new BooleanQuery.Builder(); for (String externalVal : externalVals) { Query subq = getFieldQuery(parser, field, externalVal); @@ -1120,7 +1125,7 @@ public Query getSetQuery(QParser parser, SchemaField field, Collection e * @return A suitable rewrite method for rewriting multi-term queries to primitive queries. */ public MultiTermQuery.RewriteMethod getRewriteMethod(QParser parser, SchemaField field) { - if (!field.indexed() && field.hasDocValues()) { + if (!hasIndexedTerms(field) && field.hasDocValues()) { return new DocValuesRewriteMethod(); } else { return MultiTermQuery.CONSTANT_SCORE_REWRITE; diff --git a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java index e1b7786f8ac..91a0571612f 100644 --- a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java +++ b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java @@ -18,14 +18,15 @@ package org.apache.solr.schema; import java.util.Collection; -import org.apache.lucene.document.FloatField; import org.apache.lucene.document.FloatPoint; +import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.StoredField; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.IndexableField; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.queries.function.valuesource.FloatFieldSource; import org.apache.lucene.queries.function.valuesource.MultiValuedFloatFieldSource; +import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortedNumericSelector; @@ -109,27 +110,54 @@ public Object toObject(IndexableField f) { } @Override - protected Query getExactQuery(SchemaField field, String externalVal) { - return FloatPoint.newExactQuery( - field.getName(), parseFloatFromUser(field.getName(), externalVal)); - } - - @Override - public Query getSetQuery(QParser parser, SchemaField field, Collection externalVal) { - assert externalVal.size() > 0; - if (!field.indexed()) { - return super.getSetQuery(parser, field, externalVal); - } - float[] values = new float[externalVal.size()]; - int i = 0; - for (String val : externalVal) { - values[i] = parseFloatFromUser(field.getName(), val); - i++; + public Query getSetQuery(QParser parser, SchemaField field, Collection externalVals) { + assert externalVals.size() > 0; + Query indexQuery = null; + float[] values = null; + if (hasIndexedTerms(field)) { + indexQuery = super.getSetQuery(parser, field, externalVals); + } else if (field.indexed()) { + values = new float[externalVals.size()]; + int i = 0; + for (String val : externalVals) { + values[i++] = parseFloatFromUser(field.getName(), val); + } + indexQuery = FloatPoint.newSetQuery(field.getName(), values); } if (field.hasDocValues()) { - return FloatField.newSetQuery(field.getName(), values); + long[] points = new long[externalVals.size()]; + if (values != null) { + if (field.multiValued()) { + for (int i = 0; i < values.length; i++) { + points[i] = NumericUtils.floatToSortableInt(values[i]); + } + } else { + for (int i = 0; i < values.length; i++) { + points[i] = Float.floatToIntBits(values[i]); + } + } + } else { + int i = 0; + if (field.multiValued()) { + for (String val : externalVals) { + points[i++] = NumericUtils.floatToSortableInt(parseFloatFromUser(field.getName(), val)); + } + } else { + for (String val : externalVals) { + points[i++] = Float.floatToIntBits(parseFloatFromUser(field.getName(), val)); + } + } + } + Query docValuesQuery = NumericDocValuesField.newSlowSetQuery(field.getName(), points); + if (indexQuery != null) { + return new IndexOrDocValuesQuery(indexQuery, docValuesQuery); + } else { + return docValuesQuery; + } + } else if (indexQuery != null) { + return indexQuery; } else { - return FloatPoint.newSetQuery(field.getName(), values); + return super.getSetQuery(parser, field, externalVals); } } diff --git a/solr/core/src/java/org/apache/solr/schema/IntPointField.java b/solr/core/src/java/org/apache/solr/schema/IntPointField.java index 5f44195286b..e300356c157 100644 --- a/solr/core/src/java/org/apache/solr/schema/IntPointField.java +++ b/solr/core/src/java/org/apache/solr/schema/IntPointField.java @@ -18,13 +18,14 @@ package org.apache.solr.schema; import java.util.Collection; -import org.apache.lucene.document.IntField; import org.apache.lucene.document.IntPoint; +import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.document.StoredField; import org.apache.lucene.index.IndexableField; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.queries.function.valuesource.IntFieldSource; import org.apache.lucene.queries.function.valuesource.MultiValuedIntFieldSource; +import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortedNumericSelector; @@ -104,26 +105,42 @@ public Object toObject(IndexableField f) { } @Override - protected Query getExactQuery(SchemaField field, String externalVal) { - return IntPoint.newExactQuery(field.getName(), parseIntFromUser(field.getName(), externalVal)); - } - - @Override - public Query getSetQuery(QParser parser, SchemaField field, Collection externalVal) { - assert externalVal.size() > 0; - if (!field.indexed()) { - return super.getSetQuery(parser, field, externalVal); - } - int[] values = new int[externalVal.size()]; - int i = 0; - for (String val : externalVal) { - values[i] = parseIntFromUser(field.getName(), val); - i++; + public Query getSetQuery(QParser parser, SchemaField field, Collection externalVals) { + assert externalVals.size() > 0; + Query indexQuery = null; + int[] values = null; + if (hasIndexedTerms(field)) { + indexQuery = super.getSetQuery(parser, field, externalVals); + } else if (field.indexed()) { + values = new int[externalVals.size()]; + int i = 0; + for (String val : externalVals) { + values[i++] = parseIntFromUser(field.getName(), val); + } + indexQuery = IntPoint.newSetQuery(field.getName(), values); } if (field.hasDocValues()) { - return IntField.newSetQuery(field.getName(), values); + long[] points = new long[externalVals.size()]; + if (values != null) { + for (int i = 0; i < values.length; i++) { + points[i] = values[i]; + } + } else { + int i = 0; + for (String val : externalVals) { + points[i++] = parseIntFromUser(field.getName(), val); + } + } + Query docValuesQuery = SortedNumericDocValuesField.newSlowSetQuery(field.getName(), points); + if (indexQuery != null) { + return new IndexOrDocValuesQuery(indexQuery, docValuesQuery); + } else { + return docValuesQuery; + } + } else if (indexQuery != null) { + return indexQuery; } else { - return IntPoint.newSetQuery(field.getName(), values); + return super.getSetQuery(parser, field, externalVals); } } diff --git a/solr/core/src/java/org/apache/solr/schema/LongPointField.java b/solr/core/src/java/org/apache/solr/schema/LongPointField.java index 05a014ae4e3..699e99f562b 100644 --- a/solr/core/src/java/org/apache/solr/schema/LongPointField.java +++ b/solr/core/src/java/org/apache/solr/schema/LongPointField.java @@ -18,13 +18,14 @@ package org.apache.solr.schema; import java.util.Collection; -import org.apache.lucene.document.LongField; import org.apache.lucene.document.LongPoint; +import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.document.StoredField; import org.apache.lucene.index.IndexableField; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.queries.function.valuesource.LongFieldSource; import org.apache.lucene.queries.function.valuesource.MultiValuedLongFieldSource; +import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.util.BytesRef; @@ -103,27 +104,41 @@ public Object toObject(IndexableField f) { } @Override - protected Query getExactQuery(SchemaField field, String externalVal) { - return LongPoint.newExactQuery( - field.getName(), parseLongFromUser(field.getName(), externalVal)); - } - - @Override - public Query getSetQuery(QParser parser, SchemaField field, Collection externalVal) { - assert externalVal.size() > 0; - if (!field.indexed()) { - return super.getSetQuery(parser, field, externalVal); - } - long[] values = new long[externalVal.size()]; - int i = 0; - for (String val : externalVal) { - values[i] = parseLongFromUser(field.getName(), val); - i++; + public Query getSetQuery(QParser parser, SchemaField field, Collection externalVals) { + assert externalVals.size() > 0; + Query indexQuery = null; + long[] values = null; + if (hasIndexedTerms(field)) { + indexQuery = super.getSetQuery(parser, field, externalVals); + } else if (field.indexed()) { + values = new long[externalVals.size()]; + int i = 0; + for (String val : externalVals) { + values[i++] = parseLongFromUser(field.getName(), val); + } + indexQuery = LongPoint.newSetQuery(field.getName(), values); } if (field.hasDocValues()) { - return LongField.newSetQuery(field.getName(), values); + long[] points; + if (values != null) { + points = values.clone(); + } else { + points = new long[externalVals.size()]; + int i = 0; + for (String val : externalVals) { + points[i++] = parseLongFromUser(field.getName(), val); + } + } + Query docValuesQuery = SortedNumericDocValuesField.newSlowSetQuery(field.getName(), points); + if (indexQuery != null) { + return new IndexOrDocValuesQuery(indexQuery, docValuesQuery); + } else { + return docValuesQuery; + } + } else if (indexQuery != null) { + return indexQuery; } else { - return LongPoint.newSetQuery(field.getName(), values); + return super.getSetQuery(parser, field, externalVals); } } diff --git a/solr/core/src/java/org/apache/solr/schema/PointField.java b/solr/core/src/java/org/apache/solr/schema/PointField.java index 611dcfc43a4..5f030069c5b 100644 --- a/solr/core/src/java/org/apache/solr/schema/PointField.java +++ b/solr/core/src/java/org/apache/solr/schema/PointField.java @@ -24,15 +24,19 @@ import java.util.Date; import java.util.List; import java.util.Map; +import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.SortedNumericDocValuesField; import org.apache.lucene.document.StoredField; +import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexableField; +import org.apache.lucene.index.Term; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.search.IndexOrDocValuesQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortedNumericSelector; +import org.apache.lucene.search.TermQuery; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; import org.apache.lucene.util.CharsRef; @@ -87,6 +91,11 @@ public boolean isPointField() { return true; } + @Override + protected boolean hasIndexedTerms(SchemaField field) { + return field.enhancedIndex(); + } + @Override public final ValueSource getSingleValueSource( MultiValueSelector choice, SchemaField field, QParser parser) { @@ -158,15 +167,23 @@ public Query getFieldQuery(QParser parser, SchemaField field, String externalVal // currently implemented as singleton range return getRangeQuery(parser, field, externalVal, externalVal, true, true); } else if (field.indexed() && field.hasDocValues()) { - Query pointsQuery = getExactQuery(field, externalVal); + Query indexQuery = getExactQuery(parser, field, externalVal); Query dvQuery = getDocValuesRangeQuery(parser, field, externalVal, externalVal, true, true); - return new IndexOrDocValuesQuery(pointsQuery, dvQuery); + return new IndexOrDocValuesQuery(indexQuery, dvQuery); } else { - return getExactQuery(field, externalVal); + return getExactQuery(parser, field, externalVal); } } - protected abstract Query getExactQuery(SchemaField field, String externalVal); + final Query getExactQuery(QParser parser, SchemaField field, String externalVal) { + if (hasIndexedTerms(field)) { + BytesRefBuilder br = new BytesRefBuilder(); + readableToIndexed(externalVal, br); + return new TermQuery(new Term(field.getName(), br)); + } else { + return getPointRangeQuery(parser, field, externalVal, externalVal, true, true); + } + } @Override protected Query getSpecializedRangeQuery( @@ -269,6 +286,9 @@ public List createFields(SchemaField sf, Object value) { if (sf.indexed()) { field = createField(sf, value); fields.add(field); + if (sf.enhancedIndex()) { + fields.add(new StringField(sf.getName(), field.binaryValue(), Field.Store.NO)); + } } if (sf.hasDocValues()) { diff --git a/solr/core/src/java/org/apache/solr/schema/SchemaField.java b/solr/core/src/java/org/apache/solr/schema/SchemaField.java index 2a413bf3729..3c9c882d060 100644 --- a/solr/core/src/java/org/apache/solr/schema/SchemaField.java +++ b/solr/core/src/java/org/apache/solr/schema/SchemaField.java @@ -103,6 +103,10 @@ public boolean indexed() { return (properties & INDEXED) != 0; } + public boolean enhancedIndex() { + return (properties & ENHANCED_INDEX) != 0 && indexed(); + } + @Override public boolean stored() { return (properties & STORED) != 0; diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-point.xml b/solr/core/src/test-files/solr/collection1/conf/schema-point.xml index c933d130456..4db1754682b 100644 --- a/solr/core/src/test-files/solr/collection1/conf/schema-point.xml +++ b/solr/core/src/test-files/solr/collection1/conf/schema-point.xml @@ -26,7 +26,7 @@ - + @@ -37,11 +37,15 @@ - + + + + + @@ -51,22 +55,34 @@ + + + + + + + + - + + + + + @@ -76,12 +92,20 @@ + + + + + + + + @@ -92,6 +116,10 @@ + + + + @@ -101,12 +129,20 @@ + + + + + + + + @@ -117,6 +153,10 @@ + + + + @@ -126,12 +166,20 @@ + + + + + + + + @@ -142,6 +190,10 @@ + + + + @@ -151,12 +203,20 @@ + + + + + + + + diff --git a/solr/core/src/test/org/apache/solr/schema/TestPointFields.java b/solr/core/src/test/org/apache/solr/schema/TestPointFields.java index cbee971c7cc..516b56e4a56 100644 --- a/solr/core/src/test/org/apache/solr/schema/TestPointFields.java +++ b/solr/core/src/test/org/apache/solr/schema/TestPointFields.java @@ -59,8 +59,11 @@ import org.apache.lucene.index.StoredFields; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexOrDocValuesQuery; +import org.apache.lucene.search.PointInSetQuery; import org.apache.lucene.search.PointRangeQuery; import org.apache.lucene.search.Query; +import org.apache.lucene.search.TermInSetQuery; +import org.apache.lucene.search.TermQuery; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; @@ -93,6 +96,10 @@ public class TestPointFields extends SolrTestCaseJ4 { "_dv", "_mv", "_mv_dv", + "_e", + "_e_dv", + "_e_mv", + "_e_mv_dv", "_ni", "_ni_dv", "_ni_dv_ns", @@ -105,12 +112,20 @@ public class TestPointFields extends SolrTestCaseJ4 { "_ni_ns_dv", "_dv_ns_mv", "_smf", + "_e_smf", + "_e_dv_smf", + "_e_mv_smf", + "_e_mv_dv_smf", "_dv_smf", "_mv_smf", "_mv_dv_smf", "_ni_dv_smf", "_ni_mv_dv_smf", "_sml", + "_e_sml", + "_e_dv_sml", + "_e_mv_sml", + "_e_mv_dv_sml", "_dv_sml", "_mv_sml", "_mv_dv_sml", @@ -140,6 +155,10 @@ public void testIntPointFieldExactQuery() throws Exception { doTestIntPointFieldExactQuery("number_p_i_ni_dv", false); doTestIntPointFieldExactQuery("number_p_i_ni_ns_dv", false); doTestIntPointFieldExactQuery("number_p_i_ni_mv_dv", false); + doTestIntPointFieldExactQuery("number_p_i_e", false); + doTestIntPointFieldExactQuery("number_p_i_e_mv", false); + doTestIntPointFieldExactQuery("number_p_i_e_dv", false); + doTestIntPointFieldExactQuery("number_p_i_e_mv_dv", false); } @Test @@ -162,6 +181,8 @@ public void testIntPointFieldRangeQuery() throws Exception { doTestIntPointFieldRangeQuery("number_p_i", "int", false); doTestIntPointFieldRangeQuery("number_p_i_ni_ns_dv", "int", false); doTestIntPointFieldRangeQuery("number_p_i_dv", "int", false); + doTestIntPointFieldRangeQuery("number_p_i_e", "int", false); + doTestIntPointFieldRangeQuery("number_p_i_e_dv", "int", false); } @Test @@ -186,6 +207,8 @@ public void testIntPointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_i", + "*_p_i_e", + "*_p_i_e_dv", "*_p_i_dv", "*_p_i_dv_ns", "*_p_i_ni_dv", @@ -200,9 +223,13 @@ public void testIntPointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_i_smf", + "*_p_i_e_smf", + "*_p_i_e_dv_smf", "*_p_i_dv_smf", "*_p_i_ni_dv_smf", "*_p_i_sml", + "*_p_i_e_sml", + "*_p_i_e_dv_sml", "*_p_i_dv_sml", "*_p_i_ni_dv_sml")) { assertTrue(r, regexToTest.remove(r)); @@ -224,7 +251,14 @@ public void testIntPointFieldSortAndFunction() throws Exception { // multivalued, no docvalues for (String r : Arrays.asList( - "*_p_i_mv", "*_p_i_ni_mv", "*_p_i_ni_ns_mv", "*_p_i_mv_smf", "*_p_i_mv_sml")) { + "*_p_i_mv", + "*_p_i_e_mv", + "*_p_i_e_mv_smf", + "*_p_i_e_mv_sml", + "*_p_i_ni_mv", + "*_p_i_ni_ns_mv", + "*_p_i_mv_smf", + "*_p_i_mv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -241,10 +275,17 @@ public void testIntPointFieldSortAndFunction() throws Exception { // multivalued, w/ docValues for (String r : Arrays.asList( - "*_p_i_ni_mv_dv", "*_p_i_ni_dv_ns_mv", - "*_p_i_dv_ns_mv", "*_p_i_mv_dv", - "*_p_i_mv_dv_smf", "*_p_i_ni_mv_dv_smf", - "*_p_i_mv_dv_sml", "*_p_i_ni_mv_dv_sml")) { + "*_p_i_ni_mv_dv", + "*_p_i_ni_dv_ns_mv", + "*_p_i_e_mv_dv", + "*_p_i_e_mv_dv_smf", + "*_p_i_e_mv_dv_sml", + "*_p_i_dv_ns_mv", + "*_p_i_mv_dv", + "*_p_i_mv_dv_smf", + "*_p_i_ni_mv_dv_smf", + "*_p_i_mv_dv_sml", + "*_p_i_ni_mv_dv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -269,14 +310,22 @@ public void testIntPointFieldFacetField() throws Exception { doTestPointFieldFacetField("number_p_i", "number_p_i_dv", getSequentialStringArrayWithInts(10)); clearIndex(); assertU(commit()); + doTestPointFieldFacetField( + "number_p_i_e", "number_p_i_e_dv", getSequentialStringArrayWithInts(10)); + clearIndex(); + assertU(commit()); doTestPointFieldFacetField( "number_p_i", "number_p_i_dv", toStringArray(getRandomInts(10, false))); + clearIndex(); + assertU(commit()); + doTestPointFieldFacetField( + "number_p_i_e", "number_p_i_e_dv", toStringArray(getRandomInts(10, false))); } @Test public void testIntPointFieldRangeFacet() { - String docValuesField = "number_p_i_dv"; - String nonDocValuesField = "number_p_i"; + String nonDocValuesField = "number_p_i" + (random().nextBoolean() ? "_e" : ""); + String docValuesField = nonDocValuesField + "_dv"; int numValues = 10 * RANDOM_MULTIPLIER; int numBuckets = numValues / 2; List values; @@ -425,13 +474,18 @@ public void testIntPointStats() { String[] valArray = toStringArray(values); doTestPointStats("number_p_i", "number_p_i_dv", valArray, min, max, numValues, 1, 0D); - doTestPointStats("number_p_i", "number_p_i_mv_dv", valArray, min, max, numValues, 1, 0D); + doTestPointStats("number_p_i_e", "number_p_i_e_dv", valArray, min, max, numValues, 1, 0D); + doTestPointStats("number_p_i", "number_p_i_dv", valArray, min, max, numValues, 1, 0D); + doTestPointStats("number_p_i_e_mv", "number_p_i_e_mv_dv", valArray, min, max, numValues, 1, 0D); } @Test public void testIntPointFieldMultiValuedExactQuery() throws Exception { String[] ints = toStringArray(getRandomInts(20, false)); doTestPointFieldMultiValuedExactQuery("number_p_i_mv", ints); + doTestPointFieldMultiValuedExactQuery("number_p_i_e_mv", ints); + doTestPointFieldMultiValuedExactQuery("number_p_i_e_mv_dv", ints); + doTestPointFieldMultiValuedExactQuery("number_p_i_mv_dv", ints); doTestPointFieldMultiValuedExactQuery("number_p_i_ni_mv_dv", ints); } @@ -446,6 +500,7 @@ public void testIntPointFieldMultiValuedNonSearchableExactQuery() throws Excepti public void testIntPointFieldMultiValuedReturn() throws Exception { String[] ints = toStringArray(getRandomInts(20, false)); doTestPointFieldMultiValuedReturn("number_p_i_mv", "int", ints); + doTestPointFieldMultiValuedReturn("number_p_i_e_mv", "int", ints); doTestPointFieldMultiValuedReturn("number_p_i_ni_mv_dv", "int", ints); doTestPointFieldMultiValuedReturn("number_p_i_dv_ns_mv", "int", ints); } @@ -455,8 +510,10 @@ public void testIntPointFieldMultiValuedRangeQuery() throws Exception { String[] ints = toStringArray(getRandomInts(20, false).stream().sorted().collect(Collectors.toList())); doTestPointFieldMultiValuedRangeQuery("number_p_i_mv", "int", ints); + doTestPointFieldMultiValuedRangeQuery("number_p_i_e_mv", "int", ints); doTestPointFieldMultiValuedRangeQuery("number_p_i_ni_mv_dv", "int", ints); doTestPointFieldMultiValuedRangeQuery("number_p_i_mv_dv", "int", ints); + doTestPointFieldMultiValuedRangeQuery("number_p_i_e_mv_dv", "int", ints); } @Test @@ -471,15 +528,19 @@ public void testIntPointFieldNotIndexed() throws Exception { public void testIntPointFieldMultiValuedFacetField() throws Exception { doTestPointFieldMultiValuedFacetField( "number_p_i_mv", "number_p_i_mv_dv", getSequentialStringArrayWithInts(20)); + doTestPointFieldMultiValuedFacetField( + "number_p_i_e_mv", "number_p_i_e_mv_dv", getSequentialStringArrayWithInts(20)); String[] randomSortedInts = toStringArray(getRandomInts(20, false).stream().sorted().collect(Collectors.toList())); doTestPointFieldMultiValuedFacetField("number_p_i_mv", "number_p_i_mv_dv", randomSortedInts); + doTestPointFieldMultiValuedFacetField( + "number_p_i_e_mv", "number_p_i_e_mv_dv", randomSortedInts); } @Test public void testIntPointFieldMultiValuedRangeFacet() { - String docValuesField = "number_p_i_mv_dv"; - String nonDocValuesField = "number_p_i_mv"; + String nonDocValuesField = "number_p_i" + (random().nextBoolean() ? "_e" : "") + "_mv"; + String docValuesField = nonDocValuesField + "_dv"; int numValues = 20 * RANDOM_MULTIPLIER; int numBuckets = numValues / 2; List values; @@ -634,10 +695,16 @@ public void testIntPointFieldMultiValuedRangeFacet() { public void testIntPointMultiValuedFunctionQuery() throws Exception { doTestPointMultiValuedFunctionQuery( "number_p_i_mv", "number_p_i_mv_dv", getSequentialStringArrayWithInts(20)); + doTestPointMultiValuedFunctionQuery( + "number_p_i_e_mv", "number_p_i_e_mv_dv", getSequentialStringArrayWithInts(20)); doTestPointMultiValuedFunctionQuery( "number_p_i_mv", "number_p_i_mv_dv", toStringArray(getRandomInts(20, false).stream().sorted().collect(Collectors.toList()))); + doTestPointMultiValuedFunctionQuery( + "number_p_i_e_mv", + "number_p_i_e_mv_dv", + toStringArray(getRandomInts(20, false).stream().sorted().collect(Collectors.toList()))); } @Test @@ -646,7 +713,9 @@ public void testIntPointFieldsAtomicUpdates() throws Exception { return; } doTestIntPointFieldsAtomicUpdates("number_p_i"); + doTestIntPointFieldsAtomicUpdates("number_p_i_e"); doTestIntPointFieldsAtomicUpdates("number_p_i_dv"); + doTestIntPointFieldsAtomicUpdates("number_p_i_e_dv"); doTestIntPointFieldsAtomicUpdates("number_p_i_dv_ns"); } @@ -657,6 +726,8 @@ public void testMultiValuedIntPointFieldsAtomicUpdates() throws Exception { } String[] ints = toStringArray(getRandomInts(3, false)); doTestMultiValuedPointFieldsAtomicUpdates("number_p_i_mv", "int", ints); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_i_e_mv", "int", ints); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_i_e_mv_dv", "int", ints); doTestMultiValuedPointFieldsAtomicUpdates("number_p_i_ni_mv_dv", "int", ints); doTestMultiValuedPointFieldsAtomicUpdates("number_p_i_dv_ns_mv", "int", ints); } @@ -755,6 +826,10 @@ public void testIntPointSetQuery() { doTestSetQueries("number_p_i_mv", toStringArray(getRandomInts(20, false)), true); doTestSetQueries("number_p_i_mv_dv", toStringArray(getRandomInts(20, false)), true); doTestSetQueries("number_p_i_ni_dv", toStringArray(getRandomInts(20, false)), false); + doTestSetQueries("number_p_i_e", toStringArray(getRandomInts(20, false)), false); + doTestSetQueries("number_p_i_e_dv", toStringArray(getRandomInts(20, false)), false); + doTestSetQueries("number_p_i_e_mv", toStringArray(getRandomInts(20, false)), true); + doTestSetQueries("number_p_i_e_mv_dv", toStringArray(getRandomInts(20, false)), true); } // DoublePointField @@ -769,6 +844,10 @@ public void testDoublePointFieldExactQuery() throws Exception { doTestFloatPointFieldExactQuery("number_p_d_ni_ns_dv", true); doTestFloatPointFieldExactQuery("number_p_d_ni_dv_ns", true); doTestFloatPointFieldExactQuery("number_p_d_ni_mv_dv", true); + doTestFloatPointFieldExactQuery("number_p_d_e", true); + doTestFloatPointFieldExactQuery("number_p_d_e_mv", true); + doTestFloatPointFieldExactQuery("number_p_d_e_dv", true); + doTestFloatPointFieldExactQuery("number_p_d_e_mv_dv", true); } @Test @@ -790,6 +869,8 @@ public void testDoublePointFieldRangeQuery() throws Exception { doTestFloatPointFieldRangeQuery("number_p_d", "double", true); doTestFloatPointFieldRangeQuery("number_p_d_ni_ns_dv", "double", true); doTestFloatPointFieldRangeQuery("number_p_d_dv", "double", true); + doTestFloatPointFieldRangeQuery("number_p_d_e", "double", true); + doTestFloatPointFieldRangeQuery("number_p_d_e_dv", "double", true); } @Test @@ -814,6 +895,8 @@ public void testDoublePointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_d", + "*_p_d_e", + "*_p_d_e_dv", "*_p_d_dv", "*_p_d_dv_ns", "*_p_d_ni_dv", @@ -829,9 +912,13 @@ public void testDoublePointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_d_smf", + "*_p_d_e_smf", + "*_p_d_e_dv_smf", "*_p_d_dv_smf", "*_p_d_ni_dv_smf", "*_p_d_sml", + "*_p_d_e_sml", + "*_p_d_e_dv_sml", "*_p_d_dv_sml", "*_p_d_ni_dv_sml")) { assertTrue(r, regexToTest.remove(r)); @@ -851,7 +938,14 @@ public void testDoublePointFieldSortAndFunction() throws Exception { // multivalued, no docvalues for (String r : Arrays.asList( - "*_p_d_mv", "*_p_d_ni_mv", "*_p_d_ni_ns_mv", "*_p_d_mv_smf", "*_p_d_mv_sml")) { + "*_p_d_mv", + "*_p_d_ni_mv", + "*_p_d_ni_ns_mv", + "*_p_d_mv_smf", + "*_p_d_mv_sml", + "*_p_d_e_mv", + "*_p_d_e_mv_smf", + "*_p_d_e_mv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -864,10 +958,17 @@ public void testDoublePointFieldSortAndFunction() throws Exception { // multivalued, w/ docValues for (String r : Arrays.asList( - "*_p_d_ni_mv_dv", "*_p_d_ni_dv_ns_mv", - "*_p_d_dv_ns_mv", "*_p_d_mv_dv", - "*_p_d_mv_dv_smf", "*_p_d_ni_mv_dv_smf", - "*_p_d_mv_dv_sml", "*_p_d_ni_mv_dv_sml")) { + "*_p_d_ni_mv_dv", + "*_p_d_ni_dv_ns_mv", + "*_p_d_dv_ns_mv", + "*_p_d_mv_dv", + "*_p_d_e_mv_dv", + "*_p_d_e_mv_dv_smf", + "*_p_d_e_mv_dv_sml", + "*_p_d_mv_dv_smf", + "*_p_d_ni_mv_dv_smf", + "*_p_d_mv_dv_sml", + "*_p_d_ni_mv_dv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -889,14 +990,22 @@ public void testDoublePointFieldFacetField() throws Exception { "number_p_d", "number_p_d_dv", getSequentialStringArrayWithDoubles(10)); clearIndex(); assertU(commit()); + doTestPointFieldFacetField( + "number_p_d_e", "number_p_d_e_dv", getSequentialStringArrayWithDoubles(10)); + clearIndex(); + assertU(commit()); doTestPointFieldFacetField( "number_p_d", "number_p_d_dv", toStringArray(getRandomDoubles(10, false))); + clearIndex(); + assertU(commit()); + doTestPointFieldFacetField( + "number_p_d_e", "number_p_d_e_dv", toStringArray(getRandomDoubles(10, false))); } @Test public void testDoublePointFieldRangeFacet() { - String docValuesField = "number_p_d_dv"; - String nonDocValuesField = "number_p_d"; + String nonDocValuesField = "number_p_d" + (random().nextBoolean() ? "_e" : ""); + String docValuesField = nonDocValuesField + "_dv"; int numValues = 10 * RANDOM_MULTIPLIER; int numBuckets = numValues / 2; List values, sortedValues; @@ -1057,13 +1166,19 @@ public void testDoublePointStats() { String[] valArray = toStringArray(values); doTestPointStats("number_p_d", "number_p_d_dv", valArray, min, max, numValues, 1, 1E-7D); - doTestPointStats("number_p_d", "number_p_d_mv_dv", valArray, min, max, numValues, 1, 1E-7D); + doTestPointStats("number_p_d_e", "number_p_d_e_dv", valArray, min, max, numValues, 1, 1E-7D); + doTestPointStats("number_p_d_mv", "number_p_d_mv_dv", valArray, min, max, numValues, 1, 1E-7D); + doTestPointStats( + "number_p_d_e_mv", "number_p_d_e_mv_dv", valArray, min, max, numValues, 1, 1E-7D); } @Test public void testDoublePointFieldMultiValuedExactQuery() throws Exception { String[] doubles = toStringArray(getRandomDoubles(20, false)); doTestPointFieldMultiValuedExactQuery("number_p_d_mv", doubles); + doTestPointFieldMultiValuedExactQuery("number_p_d_e_mv", doubles); + doTestPointFieldMultiValuedExactQuery("number_p_d_e_mv_dv", doubles); + doTestPointFieldMultiValuedExactQuery("number_p_d_mv_dv", doubles); doTestPointFieldMultiValuedExactQuery("number_p_d_ni_mv_dv", doubles); } @@ -1078,6 +1193,7 @@ public void testDoublePointFieldMultiValuedNonSearchableExactQuery() throws Exce public void testDoublePointFieldMultiValuedReturn() throws Exception { String[] doubles = toStringArray(getRandomDoubles(20, false)); doTestPointFieldMultiValuedReturn("number_p_d_mv", "double", doubles); + doTestPointFieldMultiValuedReturn("number_p_d_e_mv", "double", doubles); doTestPointFieldMultiValuedReturn("number_p_d_ni_mv_dv", "double", doubles); doTestPointFieldMultiValuedReturn("number_p_d_dv_ns_mv", "double", doubles); } @@ -1087,6 +1203,8 @@ public void testDoublePointFieldMultiValuedRangeQuery() throws Exception { String[] doubles = toStringArray(getRandomDoubles(20, false).stream().sorted().collect(Collectors.toList())); doTestPointFieldMultiValuedRangeQuery("number_p_d_mv", "double", doubles); + doTestPointFieldMultiValuedRangeQuery("number_p_d_e_mv", "double", doubles); + doTestPointFieldMultiValuedRangeQuery("number_p_d_e_mv_dv", "double", doubles); doTestPointFieldMultiValuedRangeQuery("number_p_d_ni_mv_dv", "double", doubles); doTestPointFieldMultiValuedRangeQuery("number_p_d_mv_dv", "double", doubles); } @@ -1095,19 +1213,23 @@ public void testDoublePointFieldMultiValuedRangeQuery() throws Exception { public void testDoublePointFieldMultiValuedFacetField() throws Exception { doTestPointFieldMultiValuedFacetField( "number_p_d_mv", "number_p_d_mv_dv", getSequentialStringArrayWithDoubles(20)); + doTestPointFieldMultiValuedFacetField( + "number_p_d_e_mv", "number_p_d_e_mv_dv", getSequentialStringArrayWithDoubles(20)); doTestPointFieldMultiValuedFacetField( "number_p_d_mv", "number_p_d_mv_dv", toStringArray(getRandomDoubles(20, false))); + doTestPointFieldMultiValuedFacetField( + "number_p_d_e_mv", "number_p_d_e_mv_dv", toStringArray(getRandomDoubles(20, false))); } @Test public void testDoublePointFieldMultiValuedRangeFacet() { - String docValuesField = "number_p_d_mv_dv"; + String nonDocValuesField = "number_p_d" + (random().nextBoolean() ? "_e" : "") + "_mv"; + String docValuesField = nonDocValuesField + "_dv"; SchemaField dvSchemaField = h.getCore().getLatestSchema().getField(docValuesField); assertTrue(dvSchemaField.multiValued()); assertTrue(dvSchemaField.hasDocValues()); assertTrue(dvSchemaField.getType() instanceof PointField); - String nonDocValuesField = "number_p_d_mv"; SchemaField nonDvSchemaField = h.getCore().getLatestSchema().getField(nonDocValuesField); assertTrue(nonDvSchemaField.multiValued()); assertFalse(nonDvSchemaField.hasDocValues()); @@ -1276,10 +1398,16 @@ public void testDoublePointFieldMultiValuedRangeFacet() { public void testDoublePointMultiValuedFunctionQuery() throws Exception { doTestPointMultiValuedFunctionQuery( "number_p_d_mv", "number_p_d_mv_dv", getSequentialStringArrayWithDoubles(20)); + doTestPointMultiValuedFunctionQuery( + "number_p_d_e_mv", "number_p_d_e_mv_dv", getSequentialStringArrayWithDoubles(20)); doTestPointMultiValuedFunctionQuery( "number_p_d_mv", "number_p_d_mv_dv", toAscendingStringArray(getRandomFloats(20, false), true)); + doTestPointMultiValuedFunctionQuery( + "number_p_d_e_mv", + "number_p_d_e_mv_dv", + toAscendingStringArray(getRandomFloats(20, false), true)); } @Test @@ -1288,7 +1416,9 @@ public void testDoublePointFieldsAtomicUpdates() throws Exception { return; } doTestDoublePointFieldsAtomicUpdates("number_p_d"); + doTestDoublePointFieldsAtomicUpdates("number_p_d_e"); doTestDoublePointFieldsAtomicUpdates("number_p_d_dv"); + doTestDoublePointFieldsAtomicUpdates("number_p_d_e_dv"); doTestDoublePointFieldsAtomicUpdates("number_p_d_dv_ns"); } @@ -1299,6 +1429,9 @@ public void testMultiValuedDoublePointFieldsAtomicUpdates() throws Exception { } String[] doubles = toStringArray(getRandomDoubles(3, false)); doTestMultiValuedPointFieldsAtomicUpdates("number_p_d_mv", "double", doubles); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_d_e_mv", "double", doubles); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_d_e_mv_dv", "double", doubles); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_d_mv_dv", "double", doubles); doTestMultiValuedPointFieldsAtomicUpdates("number_p_d_ni_mv_dv", "double", doubles); doTestMultiValuedPointFieldsAtomicUpdates("number_p_d_dv_ns_mv", "double", doubles); } @@ -1371,6 +1504,10 @@ public void testDoublePointSetQuery() { doTestSetQueries("number_p_d_mv", toStringArray(getRandomDoubles(20, false)), true); doTestSetQueries("number_p_d_mv_dv", toStringArray(getRandomDoubles(20, false)), true); doTestSetQueries("number_p_d_ni_dv", toStringArray(getRandomDoubles(20, false)), false); + doTestSetQueries("number_p_d_e", toStringArray(getRandomDoubles(20, false)), false); + doTestSetQueries("number_p_d_e_dv", toStringArray(getRandomDoubles(20, false)), false); + doTestSetQueries("number_p_d_e_mv", toStringArray(getRandomDoubles(20, false)), true); + doTestSetQueries("number_p_d_e_mv_dv", toStringArray(getRandomDoubles(20, false)), true); } // Float @@ -1385,6 +1522,10 @@ public void testFloatPointFieldExactQuery() throws Exception { doTestFloatPointFieldExactQuery("number_p_f_ni_ns_dv", false); doTestFloatPointFieldExactQuery("number_p_f_ni_dv_ns", false); doTestFloatPointFieldExactQuery("number_p_f_ni_mv_dv", false); + doTestFloatPointFieldExactQuery("number_p_f_e", false); + doTestFloatPointFieldExactQuery("number_p_f_e_mv", false); + doTestFloatPointFieldExactQuery("number_p_f_e_dv", false); + doTestFloatPointFieldExactQuery("number_p_f_e_mv_dv", false); } @Test @@ -1398,12 +1539,17 @@ public void testFloatPointFieldReturn() throws Exception { int numValues = 10 * RANDOM_MULTIPLIER; String[] floats = toStringArray(getRandomFloats(numValues, false)); doTestPointFieldReturn("number_p_f", "float", floats); + doTestPointFieldReturn("number_p_f_e", "float", floats); + doTestPointFieldReturn("number_p_f_dv", "float", floats); + doTestPointFieldReturn("number_p_f_e_dv", "float", floats); doTestPointFieldReturn("number_p_f_dv_ns", "float", floats); } @Test public void testFloatPointFieldRangeQuery() throws Exception { doTestFloatPointFieldRangeQuery("number_p_f", "float", false); + doTestFloatPointFieldRangeQuery("number_p_f_e", "float", false); + doTestFloatPointFieldRangeQuery("number_p_f_e_dv", "float", false); doTestFloatPointFieldRangeQuery("number_p_f_ni_ns_dv", "float", false); doTestFloatPointFieldRangeQuery("number_p_f_dv", "float", false); } @@ -1430,7 +1576,9 @@ public void testFloatPointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_f", + "*_p_f_e", "*_p_f_dv", + "*_p_f_e_dv", "*_p_f_dv_ns", "*_p_f_ni_dv", "*_p_f_ni_dv_ns", @@ -1445,10 +1593,14 @@ public void testFloatPointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_f_smf", + "*_p_f_e_smf", "*_p_f_dv_smf", + "*_p_f_e_dv_smf", "*_p_f_ni_dv_smf", "*_p_f_sml", + "*_p_f_e_sml", "*_p_f_dv_sml", + "*_p_f_e_dv_sml", "*_p_f_ni_dv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -1467,7 +1619,14 @@ public void testFloatPointFieldSortAndFunction() throws Exception { // multivalued, no docvalues for (String r : Arrays.asList( - "*_p_f_mv", "*_p_f_ni_mv", "*_p_f_ni_ns_mv", "*_p_f_mv_smf", "*_p_f_mv_sml")) { + "*_p_f_mv", + "*_p_f_e_mv", + "*_p_f_ni_mv", + "*_p_f_ni_ns_mv", + "*_p_f_mv_smf", + "*_p_f_e_mv_smf", + "*_p_f_mv_sml", + "*_p_f_e_mv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -1480,10 +1639,17 @@ public void testFloatPointFieldSortAndFunction() throws Exception { // multivalued, w/ docValues for (String r : Arrays.asList( - "*_p_f_ni_mv_dv", "*_p_f_ni_dv_ns_mv", - "*_p_f_dv_ns_mv", "*_p_f_mv_dv", - "*_p_f_mv_dv_smf", "*_p_f_ni_mv_dv_smf", - "*_p_f_mv_dv_sml", "*_p_f_ni_mv_dv_sml")) { + "*_p_f_ni_mv_dv", + "*_p_f_ni_dv_ns_mv", + "*_p_f_dv_ns_mv", + "*_p_f_mv_dv", + "*_p_f_e_mv_dv", + "*_p_f_e_mv_dv_smf", + "*_p_f_e_mv_dv_sml", + "*_p_f_mv_dv_smf", + "*_p_f_ni_mv_dv_smf", + "*_p_f_mv_dv_sml", + "*_p_f_ni_mv_dv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -1505,14 +1671,22 @@ public void testFloatPointFieldFacetField() throws Exception { "number_p_f", "number_p_f_dv", getSequentialStringArrayWithDoubles(10)); clearIndex(); assertU(commit()); + doTestPointFieldFacetField( + "number_p_f_e", "number_p_f_e_dv", getSequentialStringArrayWithDoubles(10)); + clearIndex(); + assertU(commit()); doTestPointFieldFacetField( "number_p_f", "number_p_f_dv", toStringArray(getRandomFloats(10, false))); + clearIndex(); + assertU(commit()); + doTestPointFieldFacetField( + "number_p_f_e", "number_p_f_e_dv", toStringArray(getRandomFloats(10, false))); } @Test public void testFloatPointFieldRangeFacet() { - String docValuesField = "number_p_f_dv"; - String nonDocValuesField = "number_p_f"; + String nonDocValuesField = "number_p_f" + (random().nextBoolean() ? "_e" : ""); + String docValuesField = nonDocValuesField + "_dv"; int numValues = 10 * RANDOM_MULTIPLIER; int numBuckets = numValues / 2; List values, sortedValues; @@ -1673,13 +1847,19 @@ public void testFloatPointStats() { String[] valArray = toStringArray(values); doTestPointStats("number_p_f", "number_p_f_dv", valArray, min, max, numValues, 1, 1E-7D); - doTestPointStats("number_p_f", "number_p_f_mv_dv", valArray, min, max, numValues, 1, 1E-7D); + doTestPointStats("number_p_f_e", "number_p_f_e_dv", valArray, min, max, numValues, 1, 1E-7D); + doTestPointStats("number_p_f_mv", "number_p_f_mv_dv", valArray, min, max, numValues, 1, 1E-7D); + doTestPointStats( + "number_p_f_e_mv", "number_p_f_e_mv_dv", valArray, min, max, numValues, 1, 1E-7D); } @Test public void testFloatPointFieldMultiValuedExactQuery() throws Exception { String[] floats = toStringArray(getRandomFloats(20, false)); doTestPointFieldMultiValuedExactQuery("number_p_f_mv", floats); + doTestPointFieldMultiValuedExactQuery("number_p_f_e_mv", floats); + doTestPointFieldMultiValuedExactQuery("number_p_f_mv_dv", floats); + doTestPointFieldMultiValuedExactQuery("number_p_f_e_mv_dv", floats); doTestPointFieldMultiValuedExactQuery("number_p_f_ni_mv_dv", floats); } @@ -1694,6 +1874,9 @@ public void testFloatPointFieldMultiValuedNonSearchableExactQuery() throws Excep public void testFloatPointFieldMultiValuedReturn() throws Exception { String[] floats = toStringArray(getRandomFloats(20, false)); doTestPointFieldMultiValuedReturn("number_p_f_mv", "float", floats); + doTestPointFieldMultiValuedReturn("number_p_f_e_mv", "float", floats); + doTestPointFieldMultiValuedReturn("number_p_f_mv_dv", "float", floats); + doTestPointFieldMultiValuedReturn("number_p_f_e_mv_dv", "float", floats); doTestPointFieldMultiValuedReturn("number_p_f_ni_mv_dv", "float", floats); doTestPointFieldMultiValuedReturn("number_p_f_dv_ns_mv", "float", floats); } @@ -1703,19 +1886,22 @@ public void testFloatPointFieldMultiValuedRangeQuery() throws Exception { String[] floats = toStringArray(getRandomFloats(20, false).stream().sorted().collect(Collectors.toList())); doTestPointFieldMultiValuedRangeQuery("number_p_f_mv", "float", floats); + doTestPointFieldMultiValuedRangeQuery("number_p_f_e_mv", "float", floats); + doTestPointFieldMultiValuedRangeQuery("number_p_f_mv_dv", "float", floats); + doTestPointFieldMultiValuedRangeQuery("number_p_f_e_mv_dv", "float", floats); doTestPointFieldMultiValuedRangeQuery("number_p_f_ni_mv_dv", "float", floats); doTestPointFieldMultiValuedRangeQuery("number_p_f_mv_dv", "float", floats); } @Test public void testFloatPointFieldMultiValuedRangeFacet() { - String docValuesField = "number_p_f_mv_dv"; + String nonDocValuesField = "number_p_f" + (random().nextBoolean() ? "_e" : "") + "_mv"; + String docValuesField = nonDocValuesField + "_dv"; SchemaField dvSchemaField = h.getCore().getLatestSchema().getField(docValuesField); assertTrue(dvSchemaField.multiValued()); assertTrue(dvSchemaField.hasDocValues()); assertTrue(dvSchemaField.getType() instanceof PointField); - String nonDocValuesField = "number_p_f_mv"; SchemaField nonDvSchemaField = h.getCore().getLatestSchema().getField(nonDocValuesField); assertTrue(nonDvSchemaField.multiValued()); assertFalse(nonDvSchemaField.hasDocValues()); @@ -1884,18 +2070,28 @@ public void testFloatPointFieldMultiValuedRangeFacet() { public void testFloatPointFieldMultiValuedFacetField() throws Exception { doTestPointFieldMultiValuedFacetField( "number_p_f_mv", "number_p_f_mv_dv", getSequentialStringArrayWithDoubles(20)); + doTestPointFieldMultiValuedFacetField( + "number_p_f_e_mv", "number_p_f_e_mv_dv", getSequentialStringArrayWithDoubles(20)); doTestPointFieldMultiValuedFacetField( "number_p_f_mv", "number_p_f_mv_dv", toStringArray(getRandomFloats(20, false))); + doTestPointFieldMultiValuedFacetField( + "number_p_f_e_mv", "number_p_f_e_mv_dv", toStringArray(getRandomFloats(20, false))); } @Test public void testFloatPointMultiValuedFunctionQuery() throws Exception { doTestPointMultiValuedFunctionQuery( "number_p_f_mv", "number_p_f_mv_dv", getSequentialStringArrayWithDoubles(20)); + doTestPointMultiValuedFunctionQuery( + "number_p_f_e_mv", "number_p_f_e_mv_dv", getSequentialStringArrayWithDoubles(20)); doTestPointMultiValuedFunctionQuery( "number_p_f_mv", "number_p_f_mv_dv", toAscendingStringArray(getRandomFloats(20, false), true)); + doTestPointMultiValuedFunctionQuery( + "number_p_f_e_mv", + "number_p_f_e_mv_dv", + toAscendingStringArray(getRandomFloats(20, false), true)); } @Test @@ -1904,7 +2100,9 @@ public void testFloatPointFieldsAtomicUpdates() throws Exception { return; } doTestFloatPointFieldsAtomicUpdates("number_p_f"); + doTestFloatPointFieldsAtomicUpdates("number_p_f_e"); doTestFloatPointFieldsAtomicUpdates("number_p_f_dv"); + doTestFloatPointFieldsAtomicUpdates("number_p_f_e_dv"); doTestFloatPointFieldsAtomicUpdates("number_p_f_dv_ns"); } @@ -1915,6 +2113,9 @@ public void testMultiValuedFloatPointFieldsAtomicUpdates() throws Exception { } String[] floats = toStringArray(getRandomFloats(3, false)); doTestMultiValuedPointFieldsAtomicUpdates("number_p_f_mv", "float", floats); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_f_e_mv", "float", floats); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_f_mv_dv", "float", floats); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_f_e_mv_dv", "float", floats); doTestMultiValuedPointFieldsAtomicUpdates("number_p_f_ni_mv_dv", "float", floats); doTestMultiValuedPointFieldsAtomicUpdates("number_p_f_dv_ns_mv", "float", floats); } @@ -1926,6 +2127,10 @@ public void testFloatPointSetQuery() { doTestSetQueries("number_p_f_mv", toStringArray(getRandomFloats(20, false)), true); doTestSetQueries("number_p_f_mv_dv", toStringArray(getRandomFloats(20, false)), true); doTestSetQueries("number_p_f_ni_dv", toStringArray(getRandomFloats(20, false)), false); + doTestSetQueries("number_p_f_e", toStringArray(getRandomFloats(20, false)), false); + doTestSetQueries("number_p_f_e_dv", toStringArray(getRandomFloats(20, false)), false); + doTestSetQueries("number_p_f_e_mv", toStringArray(getRandomFloats(20, false)), true); + doTestSetQueries("number_p_f_e_mv_dv", toStringArray(getRandomFloats(20, false)), true); } @Test @@ -1947,6 +2152,10 @@ public void testLongPointFieldExactQuery() throws Exception { doTestIntPointFieldExactQuery("number_p_l_ni_ns_dv", true); doTestIntPointFieldExactQuery("number_p_l_ni_dv_ns", true); doTestIntPointFieldExactQuery("number_p_l_ni_mv_dv", true); + doTestIntPointFieldExactQuery("number_p_l_e", true); + doTestIntPointFieldExactQuery("number_p_l_e_mv", true); + doTestIntPointFieldExactQuery("number_p_l_e_dv", true); + doTestIntPointFieldExactQuery("number_p_l_e_mv_dv", true); } @Test @@ -1960,6 +2169,9 @@ public void testLongPointFieldReturn() throws Exception { int numValues = 10 * RANDOM_MULTIPLIER; String[] longs = toStringArray(getRandomLongs(numValues, false)); doTestPointFieldReturn("number_p_l", "long", longs); + doTestPointFieldReturn("number_p_l_e", "long", longs); + doTestPointFieldReturn("number_p_l_dv", "long", longs); + doTestPointFieldReturn("number_p_l_e_dv", "long", longs); doTestPointFieldReturn("number_p_l_dv_ns", "long", longs); } @@ -2002,7 +2214,9 @@ public void testLongPointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_l", + "*_p_l_e", "*_p_l_dv", + "*_p_l_e_dv", "*_p_l_dv_ns", "*_p_l_ni_dv", "*_p_l_ni_dv_ns", @@ -2017,10 +2231,14 @@ public void testLongPointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_l_smf", + "*_p_l_e_smf", "*_p_l_dv_smf", + "*_p_l_e_dv_smf", "*_p_l_ni_dv_smf", "*_p_l_sml", + "*_p_l_e_sml", "*_p_l_dv_sml", + "*_p_l_e_dv_sml", "*_p_l_ni_dv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -2041,7 +2259,14 @@ public void testLongPointFieldSortAndFunction() throws Exception { // multivalued, no docvalues for (String r : Arrays.asList( - "*_p_l_mv", "*_p_l_ni_mv", "*_p_l_ni_ns_mv", "*_p_l_mv_smf", "*_p_l_mv_sml")) { + "*_p_l_mv", + "*_p_l_e_mv", + "*_p_l_ni_mv", + "*_p_l_ni_ns_mv", + "*_p_l_mv_smf", + "*_p_l_e_mv_smf", + "*_p_l_mv_sml", + "*_p_l_e_mv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -2057,10 +2282,17 @@ public void testLongPointFieldSortAndFunction() throws Exception { // multivalued, w/ docValues for (String r : Arrays.asList( - "*_p_l_ni_mv_dv", "*_p_l_ni_dv_ns_mv", - "*_p_l_dv_ns_mv", "*_p_l_mv_dv", - "*_p_l_mv_dv_smf", "*_p_l_ni_mv_dv_smf", - "*_p_l_mv_dv_sml", "*_p_l_ni_mv_dv_sml")) { + "*_p_l_ni_mv_dv", + "*_p_l_ni_dv_ns_mv", + "*_p_l_dv_ns_mv", + "*_p_l_mv_dv", + "*_p_l_e_mv_dv", + "*_p_l_e_mv_dv_smf", + "*_p_l_e_mv_dv_sml", + "*_p_l_mv_dv_smf", + "*_p_l_ni_mv_dv_smf", + "*_p_l_mv_dv_sml", + "*_p_l_ni_mv_dv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -2085,14 +2317,22 @@ public void testLongPointFieldFacetField() throws Exception { doTestPointFieldFacetField("number_p_l", "number_p_l_dv", getSequentialStringArrayWithInts(10)); clearIndex(); assertU(commit()); + doTestPointFieldFacetField( + "number_p_l_e", "number_p_l_e_dv", getSequentialStringArrayWithInts(10)); + clearIndex(); + assertU(commit()); doTestPointFieldFacetField( "number_p_l", "number_p_l_dv", toStringArray(getRandomLongs(10, false))); + clearIndex(); + assertU(commit()); + doTestPointFieldFacetField( + "number_p_l_e", "number_p_l_e_dv", toStringArray(getRandomLongs(10, false))); } @Test public void testLongPointFieldRangeFacet() { - String docValuesField = "number_p_l_dv"; - String nonDocValuesField = "number_p_l"; + String nonDocValuesField = "number_p_l" + (random().nextBoolean() ? "_e" : ""); + String docValuesField = nonDocValuesField + "_dv"; int numValues = 10 * RANDOM_MULTIPLIER; int numBuckets = numValues / 2; List values; @@ -2251,13 +2491,18 @@ public void testLongPointStats() { String[] valArray = toStringArray(values); doTestPointStats("number_p_l", "number_p_l_dv", valArray, min, max, numValues, 1, 0D); - doTestPointStats("number_p_l", "number_p_l_mv_dv", valArray, min, max, numValues, 1, 0D); + doTestPointStats("number_p_l_e", "number_p_l_e_dv", valArray, min, max, numValues, 1, 0D); + doTestPointStats("number_p_l_mv", "number_p_l_mv_dv", valArray, min, max, numValues, 1, 0D); + doTestPointStats("number_p_l_e_mv", "number_p_l_e_mv_dv", valArray, min, max, numValues, 1, 0D); } @Test public void testLongPointFieldMultiValuedExactQuery() throws Exception { String[] ints = toStringArray(getRandomInts(20, false)); doTestPointFieldMultiValuedExactQuery("number_p_l_mv", ints); + doTestPointFieldMultiValuedExactQuery("number_p_l_e_mv", ints); + doTestPointFieldMultiValuedExactQuery("number_p_l_mv_dv", ints); + doTestPointFieldMultiValuedExactQuery("number_p_l_e_mv_dv", ints); doTestPointFieldMultiValuedExactQuery("number_p_l_ni_mv_dv", ints); } @@ -2272,6 +2517,9 @@ public void testLongPointFieldMultiValuedNonSearchableExactQuery() throws Except public void testLongPointFieldMultiValuedReturn() throws Exception { String[] longs = toStringArray(getRandomLongs(20, false)); doTestPointFieldMultiValuedReturn("number_p_l_mv", "long", longs); + doTestPointFieldMultiValuedReturn("number_p_l_e_mv", "long", longs); + doTestPointFieldMultiValuedReturn("number_p_l_mv_dv", "long", longs); + doTestPointFieldMultiValuedReturn("number_p_l_e_mv_dv", "long", longs); doTestPointFieldMultiValuedReturn("number_p_l_ni_mv_dv", "long", longs); doTestPointFieldMultiValuedReturn("number_p_l_dv_ns_mv", "long", longs); } @@ -2281,22 +2529,28 @@ public void testLongPointFieldMultiValuedRangeQuery() throws Exception { String[] longs = toStringArray(getRandomLongs(20, false).stream().sorted().collect(Collectors.toList())); doTestPointFieldMultiValuedRangeQuery("number_p_l_mv", "long", longs); + doTestPointFieldMultiValuedRangeQuery("number_p_l_e_mv", "long", longs); doTestPointFieldMultiValuedRangeQuery("number_p_l_ni_mv_dv", "long", longs); doTestPointFieldMultiValuedRangeQuery("number_p_l_mv_dv", "long", longs); + doTestPointFieldMultiValuedRangeQuery("number_p_l_e_mv_dv", "long", longs); } @Test public void testLongPointFieldMultiValuedFacetField() throws Exception { doTestPointFieldMultiValuedFacetField( "number_p_l_mv", "number_p_l_mv_dv", getSequentialStringArrayWithInts(20)); + doTestPointFieldMultiValuedFacetField( + "number_p_l_e_mv", "number_p_l_e_mv_dv", getSequentialStringArrayWithInts(20)); doTestPointFieldMultiValuedFacetField( "number_p_l_mv", "number_p_l_mv_dv", toStringArray(getRandomLongs(20, false))); + doTestPointFieldMultiValuedFacetField( + "number_p_l_e_mv", "number_p_l_e_mv_dv", toStringArray(getRandomLongs(20, false))); } @Test public void testLongPointFieldMultiValuedRangeFacet() { - String docValuesField = "number_p_l_mv_dv"; - String nonDocValuesField = "number_p_l_mv"; + String nonDocValuesField = "number_p_l" + (random().nextBoolean() ? "_e" : "") + "_mv"; + String docValuesField = nonDocValuesField + "number_p_l_mv_dv"; int numValues = 20 * RANDOM_MULTIPLIER; int numBuckets = numValues / 2; List values; @@ -2455,10 +2709,16 @@ public void testLongPointFieldMultiValuedRangeFacet() { public void testLongPointMultiValuedFunctionQuery() throws Exception { doTestPointMultiValuedFunctionQuery( "number_p_l_mv", "number_p_l_mv_dv", getSequentialStringArrayWithInts(20)); + doTestPointMultiValuedFunctionQuery( + "number_p_l_e_mv", "number_p_l_e_mv_dv", getSequentialStringArrayWithInts(20)); doTestPointMultiValuedFunctionQuery( "number_p_l_mv", "number_p_l_mv_dv", toStringArray(getRandomLongs(20, false).stream().sorted().collect(Collectors.toList()))); + doTestPointMultiValuedFunctionQuery( + "number_p_l_e_mv", + "number_p_l_e_mv_dv", + toStringArray(getRandomLongs(20, false).stream().sorted().collect(Collectors.toList()))); } @Test @@ -2467,7 +2727,9 @@ public void testLongPointFieldsAtomicUpdates() throws Exception { return; } doTestLongPointFieldsAtomicUpdates("number_p_l"); + doTestLongPointFieldsAtomicUpdates("number_p_l_e"); doTestLongPointFieldsAtomicUpdates("number_p_l_dv"); + doTestLongPointFieldsAtomicUpdates("number_p_l_e_dv"); doTestLongPointFieldsAtomicUpdates("number_p_l_dv_ns"); } @@ -2478,6 +2740,9 @@ public void testMultiValuedLongPointFieldsAtomicUpdates() throws Exception { } String[] longs = toStringArray(getRandomLongs(3, false)); doTestMultiValuedPointFieldsAtomicUpdates("number_p_l_mv", "long", longs); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_l_e_mv", "long", longs); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_l_mv_dv", "long", longs); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_l_e_mv_dv", "long", longs); doTestMultiValuedPointFieldsAtomicUpdates("number_p_l_ni_mv_dv", "long", longs); doTestMultiValuedPointFieldsAtomicUpdates("number_p_l_dv_ns_mv", "long", longs); } @@ -2489,6 +2754,10 @@ public void testLongPointSetQuery() { doTestSetQueries("number_p_l_mv", toStringArray(getRandomLongs(20, false)), true); doTestSetQueries("number_p_l_mv_dv", toStringArray(getRandomLongs(20, false)), true); doTestSetQueries("number_p_l_ni_dv", toStringArray(getRandomLongs(20, false)), false); + doTestSetQueries("number_p_l_e", toStringArray(getRandomLongs(20, false)), false); + doTestSetQueries("number_p_l_e_dv", toStringArray(getRandomLongs(20, false)), false); + doTestSetQueries("number_p_l_e_mv", toStringArray(getRandomLongs(20, false)), true); + doTestSetQueries("number_p_l_e_mv_dv", toStringArray(getRandomLongs(20, false)), true); } @Test @@ -2522,7 +2791,11 @@ public void testDatePointFieldExactQuery() throws Exception { "number_p_dt_mv_dv", "number_p_dt_ni_dv", "number_p_dt_ni_ns_dv", - "number_p_dt_ni_mv_dv")) { + "number_p_dt_ni_mv_dv", + "number_p_dt_e", + "number_p_dt_e_mv", + "number_p_dt_e_dv", + "number_p_dt_e_mv_dv")) { doTestDatePointFieldExactQuery(field, baseDate); } } @@ -2538,12 +2811,18 @@ public void testDatePointFieldReturn() throws Exception { int numValues = 10 * RANDOM_MULTIPLIER; String[] dates = toStringArray(getRandomInstants(numValues, false)); doTestPointFieldReturn("number_p_dt", "date", dates); + doTestPointFieldReturn("number_p_dt_e", "date", dates); + doTestPointFieldReturn("number_p_dt_dv", "date", dates); + doTestPointFieldReturn("number_p_dt_e_dv", "date", dates); doTestPointFieldReturn("number_p_dt_dv_ns", "date", dates); } @Test public void testDatePointFieldRangeQuery() throws Exception { doTestDatePointFieldRangeQuery("number_p_dt"); + doTestDatePointFieldRangeQuery("number_p_dt_e"); + doTestDatePointFieldRangeQuery("number_p_dt_dv"); + doTestDatePointFieldRangeQuery("number_p_dt_e_dv"); doTestDatePointFieldRangeQuery("number_p_dt_ni_ns_dv"); } @@ -2568,7 +2847,9 @@ public void testDatePointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_dt", + "*_p_dt_e", "*_p_dt_dv", + "*_p_dt_e_dv", "*_p_dt_dv_ns", "*_p_dt_ni_dv", "*_p_dt_ni_dv_ns", @@ -2582,10 +2863,14 @@ public void testDatePointFieldSortAndFunction() throws Exception { for (String r : Arrays.asList( "*_p_dt_smf", + "*_p_dt_e_smf", "*_p_dt_dv_smf", + "*_p_dt_e_dv_smf", "*_p_dt_ni_dv_smf", "*_p_dt_sml", + "*_p_dt_e_sml", "*_p_dt_dv_sml", + "*_p_dt_e_dv_sml", "*_p_dt_ni_dv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -2604,7 +2889,14 @@ public void testDatePointFieldSortAndFunction() throws Exception { // multivalued, no docvalues for (String r : Arrays.asList( - "*_p_dt_mv", "*_p_dt_ni_mv", "*_p_dt_ni_ns_mv", "*_p_dt_mv_smf", "*_p_dt_mv_sml")) { + "*_p_dt_mv", + "*_p_dt_e_mv", + "*_p_dt_ni_mv", + "*_p_dt_ni_ns_mv", + "*_p_dt_mv_smf", + "*_p_dt_e_mv_smf", + "*_p_dt_mv_sml", + "*_p_dt_e_mv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -2619,10 +2911,17 @@ public void testDatePointFieldSortAndFunction() throws Exception { // multivalued, w/ docValues for (String r : Arrays.asList( - "*_p_dt_ni_mv_dv", "*_p_dt_ni_dv_ns_mv", - "*_p_dt_dv_ns_mv", "*_p_dt_mv_dv", - "*_p_dt_mv_dv_smf", "*_p_dt_ni_mv_dv_smf", - "*_p_dt_mv_dv_sml", "*_p_dt_ni_mv_dv_sml")) { + "*_p_dt_ni_mv_dv", + "*_p_dt_ni_dv_ns_mv", + "*_p_dt_dv_ns_mv", + "*_p_dt_mv_dv", + "*_p_dt_e_mv_dv", + "*_p_dt_e_mv_dv_smf", + "*_p_dt_e_mv_dv_sml", + "*_p_dt_mv_dv_smf", + "*_p_dt_ni_mv_dv_smf", + "*_p_dt_mv_dv_sml", + "*_p_dt_ni_mv_dv_sml")) { assertTrue(r, regexToTest.remove(r)); String field = r.replace("*", "number"); @@ -2645,8 +2944,16 @@ public void testDatePointFieldFacetField() throws Exception { "number_p_dt", "number_p_dt_dv", getSequentialStringArrayWithDates(10)); clearIndex(); assertU(commit()); + doTestPointFieldFacetField( + "number_p_dt_e", "number_p_dt_e_dv", getSequentialStringArrayWithDates(10)); + clearIndex(); + assertU(commit()); doTestPointFieldFacetField( "number_p_dt", "number_p_dt_dv", toStringArray(getRandomInstants(10, false))); + clearIndex(); + assertU(commit()); + doTestPointFieldFacetField( + "number_p_dt_e", "number_p_dt_e_dv", toStringArray(getRandomInstants(10, false))); } private static class DateGapCeiling { @@ -2705,8 +3012,8 @@ public long addTo(long millis) { @Test public void testDatePointFieldRangeFacet() { - String docValuesField = "number_p_dt_dv"; - String nonDocValuesField = "number_p_dt"; + String nonDocValuesField = "number_p_dt" + (random().nextBoolean() ? "_e" : ""); + String docValuesField = nonDocValuesField + "_dv"; int numValues = 10 * RANDOM_MULTIPLIER; int numBuckets = numValues / 2; List values, sortedValues; @@ -2868,13 +3175,18 @@ public void testDatePointFieldRangeFacet() { public void testDatePointStats() { String[] randomSortedDates = toAscendingStringArray(getRandomInstants(10, false), true); doTestDatePointStats("number_p_dt", "number_p_dt_dv", randomSortedDates); + doTestDatePointStats("number_p_dt_e", "number_p_dt_e_dv", randomSortedDates); doTestDatePointStats("number_p_dt_mv", "number_p_dt_mv_dv", randomSortedDates); + doTestDatePointStats("number_p_dt_e_mv", "number_p_dt_e_mv_dv", randomSortedDates); } @Test public void testDatePointFieldMultiValuedExactQuery() throws Exception { String[] dates = toStringArray(getRandomInstants(20, false)); doTestPointFieldMultiValuedExactQuery("number_p_dt_mv", dates); + doTestPointFieldMultiValuedExactQuery("number_p_dt_e_mv", dates); + doTestPointFieldMultiValuedExactQuery("number_p_dt_mv_dv", dates); + doTestPointFieldMultiValuedExactQuery("number_p_dt_e_mv_dv", dates); doTestPointFieldMultiValuedExactQuery("number_p_dt_ni_mv_dv", dates); } @@ -2889,6 +3201,9 @@ public void testDatePointFieldMultiValuedNonSearchableExactQuery() throws Except public void testDatePointFieldMultiValuedReturn() throws Exception { String[] dates = toStringArray(getRandomInstants(20, false)); doTestPointFieldMultiValuedReturn("number_p_dt_mv", "date", dates); + doTestPointFieldMultiValuedReturn("number_p_dt_e_mv", "date", dates); + doTestPointFieldMultiValuedReturn("number_p_dt_mv_dv", "date", dates); + doTestPointFieldMultiValuedReturn("number_p_dt_e_mv_dv", "date", dates); doTestPointFieldMultiValuedReturn("number_p_dt_ni_mv_dv", "date", dates); doTestPointFieldMultiValuedReturn("number_p_dt_dv_ns_mv", "date", dates); } @@ -2898,6 +3213,9 @@ public void testDatePointFieldMultiValuedRangeQuery() throws Exception { String[] dates = toStringArray(getRandomInstants(20, false).stream().sorted().collect(Collectors.toList())); doTestPointFieldMultiValuedRangeQuery("number_p_dt_mv", "date", dates); + doTestPointFieldMultiValuedRangeQuery("number_p_dt_e_mv", "date", dates); + doTestPointFieldMultiValuedRangeQuery("number_p_dt_mv_dv", "date", dates); + doTestPointFieldMultiValuedRangeQuery("number_p_dt_e_mv_dv", "date", dates); doTestPointFieldMultiValuedRangeQuery("number_p_dt_ni_mv_dv", "date", dates); } @@ -2905,19 +3223,23 @@ public void testDatePointFieldMultiValuedRangeQuery() throws Exception { public void testDatePointFieldMultiValuedFacetField() throws Exception { doTestPointFieldMultiValuedFacetField( "number_p_dt_mv", "number_p_dt_mv_dv", getSequentialStringArrayWithDates(20)); + doTestPointFieldMultiValuedFacetField( + "number_p_dt_e_mv", "number_p_dt_e_mv_dv", getSequentialStringArrayWithDates(20)); doTestPointFieldMultiValuedFacetField( "number_p_dt_mv", "number_p_dt_mv_dv", toStringArray(getRandomInstants(20, false))); + doTestPointFieldMultiValuedFacetField( + "number_p_dt_e_mv", "number_p_dt_e_mv_dv", toStringArray(getRandomInstants(20, false))); } @Test public void testDatePointFieldMultiValuedRangeFacet() { - String docValuesField = "number_p_dt_mv_dv"; + String nonDocValuesField = "number_p_dt" + (random().nextBoolean() ? "_e" : "") + "_mv"; + String docValuesField = nonDocValuesField + "_dv"; SchemaField dvSchemaField = h.getCore().getLatestSchema().getField(docValuesField); assertTrue(dvSchemaField.multiValued()); assertTrue(dvSchemaField.hasDocValues()); assertTrue(dvSchemaField.getType() instanceof PointField); - String nonDocValuesField = "number_p_dt_mv"; SchemaField nonDvSchemaField = h.getCore().getLatestSchema().getField(nonDocValuesField); assertTrue(nonDvSchemaField.multiValued()); assertFalse(nonDvSchemaField.hasDocValues()); @@ -3092,6 +3414,7 @@ public void testDatePointMultiValuedFunctionQuery() throws Exception { String[] dates = toStringArray(getRandomInstants(20, false).stream().sorted().collect(Collectors.toList())); doTestPointMultiValuedFunctionQuery("number_p_dt_mv", "number_p_dt_mv_dv", dates); + doTestPointMultiValuedFunctionQuery("number_p_dt_e_mv", "number_p_dt_e_mv_dv", dates); } @Test @@ -3100,7 +3423,9 @@ public void testDatePointFieldsAtomicUpdates() throws Exception { return; } doTestDatePointFieldsAtomicUpdates("number_p_dt"); + doTestDatePointFieldsAtomicUpdates("number_p_dt_e"); doTestDatePointFieldsAtomicUpdates("number_p_dt_dv"); + doTestDatePointFieldsAtomicUpdates("number_p_dt_e_dv"); doTestDatePointFieldsAtomicUpdates("number_p_dt_dv_ns"); } @@ -3115,6 +3440,9 @@ public void testMultiValuedDatePointFieldsAtomicUpdates() throws Exception { .map(Object::toString) .toArray(String[]::new); doTestMultiValuedPointFieldsAtomicUpdates("number_p_dt_mv", "date", dates); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_dt_e_mv", "date", dates); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_dt_mv_dv", "date", dates); + doTestMultiValuedPointFieldsAtomicUpdates("number_p_dt_e_mv_dv", "date", dates); doTestMultiValuedPointFieldsAtomicUpdates("number_p_dt_ni_mv_dv", "date", dates); doTestMultiValuedPointFieldsAtomicUpdates("number_p_dt_dv_ns_mv", "date", dates); } @@ -3126,6 +3454,10 @@ public void testDatePointSetQuery() { doTestSetQueries("number_p_dt_mv", toStringArray(getRandomInstants(20, false)), true); doTestSetQueries("number_p_dt_mv_dv", toStringArray(getRandomInstants(20, false)), true); doTestSetQueries("number_p_dt_ni_dv", toStringArray(getRandomInstants(20, false)), false); + doTestSetQueries("number_p_dt_e", toStringArray(getRandomInstants(20, false)), false); + doTestSetQueries("number_p_dt_e_dv", toStringArray(getRandomInstants(20, false)), false); + doTestSetQueries("number_p_dt_e_mv", toStringArray(getRandomInstants(20, false)), true); + doTestSetQueries("number_p_dt_e_mv_dv", toStringArray(getRandomInstants(20, false)), true); } @Test @@ -3162,36 +3494,139 @@ public void testIndexOrDocValuesQuery() { fieldTypeNames.length == fieldTypes.length && fieldTypeNames.length == max.length && fieldTypeNames.length == min.length); + Query q; for (int i = 0; i < fieldTypeNames.length; i++) { - SchemaField fieldIndexed = h.getCore().getLatestSchema().getField("foo_" + fieldTypeNames[i]); + SchemaField fieldIndexed = h.getCore().getLatestSchema().getField("foo" + fieldTypeNames[i]); SchemaField fieldIndexedAndDv = - h.getCore().getLatestSchema().getField("foo_" + fieldTypeNames[i] + "_dv"); + h.getCore().getLatestSchema().getField("foo" + fieldTypeNames[i] + "_dv"); SchemaField fieldIndexedMv = - h.getCore().getLatestSchema().getField("foo_" + fieldTypeNames[i] + "_mv"); + h.getCore().getLatestSchema().getField("foo" + fieldTypeNames[i] + "_mv"); SchemaField fieldIndexedAndDvMv = - h.getCore().getLatestSchema().getField("foo_" + fieldTypeNames[i] + "_mv_dv"); + h.getCore().getLatestSchema().getField("foo" + fieldTypeNames[i] + "_mv_dv"); assertTrue( fieldTypes[i].getRangeQuery(null, fieldIndexed, min[i], max[i], true, true) instanceof PointRangeQuery); - assertTrue( - fieldTypes[i].getRangeQuery(null, fieldIndexedAndDv, min[i], max[i], true, true) - instanceof IndexOrDocValuesQuery); + String expectedDocValuesRangeQueryClass = + ((fieldTypeNames[i].endsWith("d") || fieldTypeNames[i].endsWith("f")) + && min[i].startsWith("-") + && !max[i].startsWith("-")) + ? "FunctionRangeQuery" + : "SortedNumericDocValuesRangeQuery"; + q = fieldTypes[i].getRangeQuery(null, fieldIndexedAndDv, min[i], max[i], true, true); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof PointRangeQuery); + assertEquals( + expectedDocValuesRangeQueryClass, + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); assertTrue( fieldTypes[i].getRangeQuery(null, fieldIndexedMv, min[i], max[i], true, true) instanceof PointRangeQuery); - assertTrue( - fieldTypes[i].getRangeQuery(null, fieldIndexedAndDvMv, min[i], max[i], true, true) - instanceof IndexOrDocValuesQuery); + q = fieldTypes[i].getRangeQuery(null, fieldIndexedAndDvMv, min[i], max[i], true, true); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof PointRangeQuery); + assertEquals( + "SortedNumericDocValuesRangeQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); assertTrue( fieldTypes[i].getFieldQuery(null, fieldIndexed, min[i]) instanceof PointRangeQuery); - assertTrue( - fieldTypes[i].getFieldQuery(null, fieldIndexedAndDv, min[i]) - instanceof IndexOrDocValuesQuery); + q = fieldTypes[i].getFieldQuery(null, fieldIndexedAndDv, min[i]); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof PointRangeQuery); + assertEquals( + "SortedNumericDocValuesRangeQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); assertTrue( fieldTypes[i].getFieldQuery(null, fieldIndexedMv, min[i]) instanceof PointRangeQuery); + q = fieldTypes[i].getFieldQuery(null, fieldIndexedAndDvMv, min[i]); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof PointRangeQuery); + assertEquals( + "SortedNumericDocValuesRangeQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); + assertTrue( + fieldTypes[i].getSetQuery(null, fieldIndexed, List.of(min[i], max[i])) + instanceof PointInSetQuery); + q = fieldTypes[i].getSetQuery(null, fieldIndexedAndDv, List.of(min[i], max[i])); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof PointInSetQuery); + assertEquals( + "SortedNumericDocValuesSetQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); + assertTrue( + fieldTypes[i].getSetQuery(null, fieldIndexedMv, List.of(min[i], max[i])) + instanceof PointInSetQuery); + q = fieldTypes[i].getSetQuery(null, fieldIndexedAndDvMv, List.of(min[i], max[i])); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof PointInSetQuery); + assertEquals( + "SortedNumericDocValuesSetQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); + } + for (int i = 0; i < fieldTypeNames.length; i++) { + SchemaField fieldIndexed = + h.getCore().getLatestSchema().getField("foo" + fieldTypeNames[i] + "_e"); + SchemaField fieldIndexedAndDv = + h.getCore().getLatestSchema().getField("foo" + fieldTypeNames[i] + "_e_dv"); + SchemaField fieldIndexedMv = + h.getCore().getLatestSchema().getField("foo" + fieldTypeNames[i] + "_e_mv"); + SchemaField fieldIndexedAndDvMv = + h.getCore().getLatestSchema().getField("foo" + fieldTypeNames[i] + "_e_mv_dv"); + assertTrue( + fieldTypes[i].getRangeQuery(null, fieldIndexed, min[i], max[i], true, true) + instanceof PointRangeQuery); + String expectedDocValuesRangeQueryClass = + ((fieldTypeNames[i].endsWith("d") || fieldTypeNames[i].endsWith("f")) + && min[i].startsWith("-") + && !max[i].startsWith("-")) + ? "FunctionRangeQuery" + : "SortedNumericDocValuesRangeQuery"; + q = fieldTypes[i].getRangeQuery(null, fieldIndexedAndDv, min[i], max[i], true, true); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof PointRangeQuery); + assertEquals( + expectedDocValuesRangeQueryClass, + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); + assertTrue( + fieldTypes[i].getRangeQuery(null, fieldIndexedMv, min[i], max[i], true, true) + instanceof PointRangeQuery); + q = fieldTypes[i].getRangeQuery(null, fieldIndexedAndDvMv, min[i], max[i], true, true); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof PointRangeQuery); + assertEquals( + "SortedNumericDocValuesRangeQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); + assertTrue(fieldTypes[i].getFieldQuery(null, fieldIndexed, min[i]) instanceof TermQuery); + q = fieldTypes[i].getFieldQuery(null, fieldIndexedAndDv, min[i]); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof TermQuery); + assertEquals( + "SortedNumericDocValuesRangeQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); + assertTrue(fieldTypes[i].getFieldQuery(null, fieldIndexedMv, min[i]) instanceof TermQuery); + q = fieldTypes[i].getFieldQuery(null, fieldIndexedAndDvMv, min[i]); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof TermQuery); + assertEquals( + "SortedNumericDocValuesRangeQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); + assertTrue( + fieldTypes[i].getSetQuery(null, fieldIndexed, List.of(min[i], max[i])) + instanceof TermInSetQuery); + q = fieldTypes[i].getSetQuery(null, fieldIndexedAndDv, List.of(min[i], max[i])); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof TermInSetQuery); + assertEquals( + "SortedNumericDocValuesSetQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); assertTrue( - fieldTypes[i].getFieldQuery(null, fieldIndexedAndDvMv, min[i]) - instanceof IndexOrDocValuesQuery); + fieldTypes[i].getSetQuery(null, fieldIndexedMv, List.of(min[i], max[i])) + instanceof TermInSetQuery); + q = fieldTypes[i].getSetQuery(null, fieldIndexedAndDvMv, List.of(min[i], max[i])); + assertTrue(q instanceof IndexOrDocValuesQuery); + assertTrue(((IndexOrDocValuesQuery) q).getIndexQuery() instanceof TermInSetQuery); + assertEquals( + "SortedNumericDocValuesSetQuery", + ((IndexOrDocValuesQuery) q).getRandomAccessQuery().getClass().getSimpleName()); } } @@ -5319,35 +5754,20 @@ private void doTestSetQueries(String fieldName, String[] values, boolean multiVa } } builder.append(')'); - if (sf.indexed()) { // SolrQueryParser should also be generating a PointInSetQuery if indexed - assertQ( - req( - CommonParams.DEBUG, - CommonParams.QUERY, - "q", - "*:*", - "fq", - builder.toString(), - "fl", - "id," + fieldName), - "//*[@numFound='" + numTerms + "']", - "//*[@name='parsed_filter_queries']/str[.='" - + getSetQueryToString(fieldName, values, numTerms) - + "']"); - } else { - // Won't use PointInSetQuery if the field is not indexed, but should match the same docs - assertQ( - req( - CommonParams.DEBUG, - CommonParams.QUERY, - "q", - "*:*", - "fq", - builder.toString(), - "fl", - "id," + fieldName), - "//*[@numFound='" + numTerms + "']"); - } + assertQ( + req( + CommonParams.DEBUG, + CommonParams.QUERY, + "q", + "*:*", + "fq", + builder.toString(), + "fl", + "id," + fieldName), + "//*[@numFound='" + numTerms + "']", + "//*[@name='parsed_filter_queries']/str[" + + getSetQueryToString(fieldName, values, numTerms) + + "]"); if (multiValued) { clearIndex(); @@ -5388,12 +5808,33 @@ private void doTestSetQueries(String fieldName, String[] values, boolean multiVa private String getSetQueryToString(String fieldName, String[] values, int numTerms) { SchemaField sf = h.getCore().getLatestSchema().getField(fieldName); - Query setQuery = - sf.getType().getSetQuery(null, sf, Arrays.asList(Arrays.copyOf(values, numTerms))); + List rules = new ArrayList<>(); + boolean isMultiQuery = false; if (sf.indexed() && sf.hasDocValues()) { - return IndexOrDocValuesQuery.class.getSimpleName() + "(" + setQuery.toString() + ")"; + isMultiQuery = true; + rules.add("starts-with(., 'IndexOrDocValuesQuery')"); + } + if (sf.enhancedIndex()) { + if (isMultiQuery) { + rules.add("contains(., 'indexQuery=" + fieldName + ":(')"); + } else { + rules.add("starts-with(., 'TermInSetQuery(" + fieldName + ":(')"); + } + } else if (sf.indexed()) { + if (isMultiQuery) { + rules.add("contains(., 'indexQuery=" + fieldName + ":{')"); + } else { + rules.add("starts-with(., '(" + fieldName + ":{')"); + } + } + if (sf.hasDocValues()) { + if (isMultiQuery) { + rules.add("contains(., 'dvQuery=" + fieldName + ": [')"); + } else { + rules.add("starts-with(., 'SortedNumericDocValuesSetQuery(" + fieldName + ": [')"); + } } - return "(" + setQuery.toString() + ")"; + return String.join(" and ", rules); } private void doTestDatePointFieldExactQuery(final String field, final String baseDate)