mirror of https://github.com/apache/lucene.git
SOLR-9187: Support dates and booleans in /export handler, support boolean DocValues fields
This commit is contained in:
parent
79d1b8c227
commit
844ca4a348
|
@ -47,6 +47,19 @@ Optimizations
|
|||
|
||||
================== 6.2.0 ==================
|
||||
|
||||
|
||||
Upgrading from Solr any prior release
|
||||
----------------------
|
||||
|
||||
Detailed Change List
|
||||
----------------------
|
||||
|
||||
New Features
|
||||
----------------------
|
||||
|
||||
* SOLR-9187: Support dates and booleans in /export handler, support boolean DocValues fields
|
||||
|
||||
|
||||
Bug Fixes
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -554,8 +554,8 @@ public class SimpleFacets {
|
|||
|
||||
/*The user did not specify any preference*/
|
||||
if (method == null) {
|
||||
/* Always use filters for booleans... we know the number of values is very small. */
|
||||
if (type instanceof BoolField) {
|
||||
/* Always use filters for booleans if not DocValues only... we know the number of values is very small. */
|
||||
if (type instanceof BoolField && (field.indexed() == true || field.hasDocValues() == false)) {
|
||||
method = FacetMethod.ENUM;
|
||||
} else if (type.getNumericType() != null && !field.multiValued()) {
|
||||
/* the per-segment approach is optimal for numeric field types since there
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
@ -44,10 +45,12 @@ import org.apache.solr.common.params.SolrParams;
|
|||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.request.SolrRequestInfo;
|
||||
import org.apache.solr.schema.BoolField;
|
||||
import org.apache.solr.schema.FieldType;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.SchemaField;
|
||||
import org.apache.solr.schema.StrField;
|
||||
import org.apache.solr.schema.TrieDateField;
|
||||
import org.apache.solr.schema.TrieDoubleField;
|
||||
import org.apache.solr.schema.TrieFloatField;
|
||||
import org.apache.solr.schema.TrieIntField;
|
||||
|
@ -99,14 +102,24 @@ public class SortingResponseWriter implements QueryResponseWriter {
|
|||
exception = new IOException(new SyntaxError("Scoring is not currently supported with xsort."));
|
||||
}
|
||||
|
||||
FixedBitSet[] sets = (FixedBitSet[])req.getContext().get("export");
|
||||
Integer th = (Integer)req.getContext().get("totalHits");
|
||||
|
||||
if(sets == null) {
|
||||
exception = new IOException(new SyntaxError("xport RankQuery is required for xsort: rq={!xport}"));
|
||||
// There is a bailout in SolrIndexSearcher.getDocListNC when there are _no_ docs in the index at all.
|
||||
// if (lastDocRequested <= 0) {
|
||||
// That causes the totalHits and export entries in the context to _not_ get set.
|
||||
// The only time that really matters is when we search against an _empty_ set. That's too obscure
|
||||
// a condition to handle as part of this patch, if someone wants to pursue it it can be reproduced with:
|
||||
// ant test -Dtestcase=StreamingTest -Dtests.method=testAllValidExportTypes -Dtests.seed=10F13879D0D1D6AD -Dtests.slow=true -Dtests.locale=es-PA -Dtests.timezone=America/Bahia_Banderas -Dtests.asserts=true -Dtests.file.encoding=ISO-8859-1
|
||||
// You'll have to uncomment the if below to hit the null pointer exception.
|
||||
// This is such an unusual case (i.e. an empty index) that catching this concdition here is probably OK.
|
||||
// This came to light in the very artifical case of indexing a single doc to Cloud.
|
||||
int totalHits = 0;
|
||||
FixedBitSet[] sets = null;
|
||||
if (req.getContext().get("totalHits") != null) {
|
||||
totalHits = ((Integer)req.getContext().get("totalHits")).intValue();
|
||||
sets = (FixedBitSet[]) req.getContext().get("export");
|
||||
if (sets == null) {
|
||||
exception = new IOException(new SyntaxError("xport RankQuery is required for xsort: rq={!xport}"));
|
||||
}
|
||||
}
|
||||
|
||||
int totalHits = th.intValue();
|
||||
SolrParams params = req.getParams();
|
||||
String fl = params.get("fl");
|
||||
|
||||
|
@ -132,7 +145,7 @@ public class SortingResponseWriter implements QueryResponseWriter {
|
|||
|
||||
try {
|
||||
fieldWriters = getFieldWriters(fields, req.getSearcher());
|
||||
}catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
|
||||
|
@ -309,8 +322,21 @@ public class SortingResponseWriter implements QueryResponseWriter {
|
|||
} else {
|
||||
writers[i] = new StringFieldWriter(field, fieldType);
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Export fields must either be one of the following types: int,float,long,double,string");
|
||||
} else if (fieldType instanceof TrieDateField) {
|
||||
if (multiValued) {
|
||||
writers[i] = new MultiFieldWriter(field, fieldType, false);
|
||||
} else {
|
||||
writers[i] = new DateFieldWriter(field);
|
||||
}
|
||||
} else if(fieldType instanceof BoolField) {
|
||||
if(multiValued) {
|
||||
writers[i] = new MultiFieldWriter(field, fieldType, true);
|
||||
} else {
|
||||
writers[i] = new BoolFieldWriter(field, fieldType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IOException("Export fields must either be one of the following types: int,float,long,double,string,date,boolean");
|
||||
}
|
||||
}
|
||||
return writers;
|
||||
|
@ -362,8 +388,25 @@ public class SortingResponseWriter implements QueryResponseWriter {
|
|||
} else {
|
||||
sortValues[i] = new StringValue(vals, field, new IntAsc());
|
||||
}
|
||||
} else if (ft instanceof TrieDateField) {
|
||||
if (reverse) {
|
||||
sortValues[i] = new LongValue(field, new LongDesc());
|
||||
} else {
|
||||
sortValues[i] = new LongValue(field, new LongAsc());
|
||||
}
|
||||
} else if (ft instanceof BoolField) {
|
||||
// This is a bit of a hack, but since the boolean field stores ByteRefs, just like Strings
|
||||
// _and_ since "F" happens to sort before "T" (thus false sorts "less" than true)
|
||||
// we can just use the existing StringValue here.
|
||||
LeafReader reader = searcher.getLeafReader();
|
||||
SortedDocValues vals = reader.getSortedDocValues(field);
|
||||
if(reverse) {
|
||||
sortValues[i] = new StringValue(vals, field, new IntDesc());
|
||||
} else {
|
||||
sortValues[i] = new StringValue(vals, field, new IntAsc());
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Sort fields must be one of the following types: int,float,long,double,string");
|
||||
throw new IOException("Sort fields must be one of the following types: int,float,long,double,string,date,boolean");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1296,6 +1339,65 @@ public class SortingResponseWriter implements QueryResponseWriter {
|
|||
}
|
||||
}
|
||||
|
||||
class DateFieldWriter extends FieldWriter {
|
||||
private String field;
|
||||
|
||||
public DateFieldWriter(String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public boolean write(int docId, LeafReader reader, Writer out, int fieldIndex) throws IOException {
|
||||
NumericDocValues vals = DocValues.getNumeric(reader, this.field);
|
||||
long val = vals.get(docId);
|
||||
|
||||
if (fieldIndex > 0) {
|
||||
out.write(',');
|
||||
}
|
||||
out.write('"');
|
||||
out.write(this.field);
|
||||
out.write('"');
|
||||
out.write(':');
|
||||
out.write('"');
|
||||
writeStr(new Date(val).toInstant().toString(), out);
|
||||
out.write('"');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class BoolFieldWriter extends FieldWriter {
|
||||
private String field;
|
||||
private FieldType fieldType;
|
||||
private CharsRefBuilder cref = new CharsRefBuilder();
|
||||
|
||||
public BoolFieldWriter(String field, FieldType fieldType) {
|
||||
this.field = field;
|
||||
this.fieldType = fieldType;
|
||||
}
|
||||
|
||||
public boolean write(int docId, LeafReader reader, Writer out, int fieldIndex) throws IOException {
|
||||
SortedDocValues vals = DocValues.getSorted(reader, this.field);
|
||||
int ord = vals.getOrd(docId);
|
||||
if(ord == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BytesRef ref = vals.lookupOrd(ord);
|
||||
fieldType.indexedToReadable(ref, cref);
|
||||
|
||||
if (fieldIndex > 0) {
|
||||
out.write(',');
|
||||
}
|
||||
out.write('"');
|
||||
out.write(this.field);
|
||||
out.write('"');
|
||||
out.write(':');
|
||||
//out.write('"');
|
||||
writeStr(cref.toString(), out);
|
||||
//out.write('"');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class FloatFieldWriter extends FieldWriter {
|
||||
private String field;
|
||||
|
||||
|
@ -1614,4 +1716,4 @@ public class SortingResponseWriter implements QueryResponseWriter {
|
|||
return (Object[]) heap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,11 +17,16 @@
|
|||
package org.apache.solr.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.Tokenizer;
|
||||
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
|
||||
import org.apache.lucene.document.SortedDocValuesField;
|
||||
import org.apache.lucene.document.SortedSetDocValuesField;
|
||||
import org.apache.lucene.index.DocValues;
|
||||
import org.apache.lucene.index.IndexableField;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
|
@ -123,7 +128,11 @@ public class BoolField extends PrimitiveFieldType {
|
|||
|
||||
@Override
|
||||
public String toExternal(IndexableField f) {
|
||||
return indexedToReadable(f.stringValue());
|
||||
if (f.binaryValue() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return indexedToReadable(f.binaryValue().utf8ToString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -144,7 +153,7 @@ public class BoolField extends PrimitiveFieldType {
|
|||
|
||||
private static final CharsRef TRUE = new CharsRef("true");
|
||||
private static final CharsRef FALSE = new CharsRef("false");
|
||||
|
||||
|
||||
@Override
|
||||
public CharsRef indexedToReadable(BytesRef input, CharsRefBuilder charsRef) {
|
||||
if (input.length > 0 && input.bytes[input.offset] == 'T') {
|
||||
|
@ -169,6 +178,36 @@ public class BoolField extends PrimitiveFieldType {
|
|||
public Object unmarshalSortValue(Object value) {
|
||||
return unmarshalStringSortValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IndexableField> createFields(SchemaField field, Object value, float boost) {
|
||||
IndexableField fval = createField(field, value, boost);
|
||||
|
||||
if (field.hasDocValues()) {
|
||||
IndexableField docval;
|
||||
final BytesRef bytes = new BytesRef(toInternal(value.toString()));
|
||||
if (field.multiValued()) {
|
||||
docval = new SortedSetDocValuesField(field.getName(), bytes);
|
||||
} else {
|
||||
docval = new SortedDocValuesField(field.getName(), bytes);
|
||||
}
|
||||
|
||||
// Only create a list of we have 2 values...
|
||||
if (fval != null) {
|
||||
List<IndexableField> fields = new ArrayList<>(2);
|
||||
fields.add(fval);
|
||||
fields.add(docval);
|
||||
return fields;
|
||||
}
|
||||
|
||||
fval = docval;
|
||||
}
|
||||
return Collections.singletonList(fval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkSchemaField(final SchemaField field) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - this can be much more efficient - use FixedBitSet or Bits
|
||||
|
|
|
@ -112,6 +112,7 @@ import org.apache.solr.request.LocalSolrQueryRequest;
|
|||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.request.SolrRequestInfo;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.schema.BoolField;
|
||||
import org.apache.solr.schema.EnumField;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.SchemaField;
|
||||
|
@ -841,8 +842,15 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
|
|||
break;
|
||||
case SORTED:
|
||||
SortedDocValues sdv = leafReader.getSortedDocValues(fieldName);
|
||||
if (sdv.getOrd(docid) >= 0) {
|
||||
doc.addField(fieldName, sdv.get(docid).utf8ToString());
|
||||
int ord = sdv.getOrd(docid);
|
||||
if (ord >= 0) {
|
||||
// Special handling for Boolean fields since they're stored as 'T' and 'F'.
|
||||
if (schemaField.getType() instanceof BoolField) {
|
||||
final BytesRef bRef = sdv.lookupOrd(ord);
|
||||
doc.addField(fieldName, schemaField.getType().toObject(schemaField, bRef));
|
||||
} else {
|
||||
doc.addField(fieldName, sdv.get(docid).utf8ToString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SORTED_NUMERIC:
|
||||
|
|
|
@ -61,7 +61,8 @@
|
|||
<field name="longdv" type="long" indexed="false" stored="false" docValues="true" default="4"/>
|
||||
<field name="datedv" type="date" indexed="false" stored="false" docValues="true" default="1995-12-31T23:59:59.999Z"/>
|
||||
|
||||
<field name="stringdv" type="string" indexed="false" stored="false" docValues="true" default="solr"/>
|
||||
<field name="stringdv" type="string" indexed="false" stored="false" docValues="true" default="solr" />
|
||||
<field name="booldv" type="boolean" indexed="false" stored="false" docValues="true" default="true" />
|
||||
|
||||
<field name="floatdvs" type="float" indexed="false" stored="false" docValues="true" default="1"/>
|
||||
<field name="intdvs" type="int" indexed="false" stored="false" docValues="true" default="2"/>
|
||||
|
@ -69,7 +70,7 @@
|
|||
<field name="longdvs" type="long" indexed="false" stored="false" docValues="true" default="4"/>
|
||||
<field name="datedvs" type="date" indexed="false" stored="false" docValues="true" default="1995-12-31T23:59:59.999Z"/>
|
||||
<field name="stringdvs" type="string" indexed="false" stored="false" docValues="true" default="solr"/>
|
||||
|
||||
<field name="booldvs" type="boolean" indexed="false" stored="false" docValues="true" default="true"/>
|
||||
|
||||
<uniqueKey>id</uniqueKey>
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="date" class="solr.TrieDateField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="string" class="solr.StrField"/>
|
||||
<fieldType name="boolean" class="solr.BoolField"/>
|
||||
|
||||
<field name="id" type="string" required="true"/>
|
||||
|
||||
|
@ -61,6 +62,13 @@
|
|||
sortMissingLast="true"/>
|
||||
|
||||
|
||||
<field name="booldv" type="boolean" indexed="false" stored="false" docValues="true"/>
|
||||
<field name="booldv_missingfirst" type="boolean" indexed="false" stored="false" docValues="true"
|
||||
sortMissingFirst="true"/>
|
||||
<field name="booldv_missinglast" type="boolean" indexed="false" stored="false" docValues="true"
|
||||
sortMissingLast="true"/>
|
||||
|
||||
|
||||
<dynamicField name="*_floatdv" type="float" indexed="false" stored="false" docValues="true"/>
|
||||
<dynamicField name="*_floatdv_missingfirst" type="float" indexed="false" stored="false" docValues="true"
|
||||
sortMissingFirst="true"/>
|
||||
|
@ -97,6 +105,11 @@
|
|||
<dynamicField name="*_stringdv_missinglast" type="string" indexed="false" stored="false" docValues="true"
|
||||
sortMissingLast="true"/>
|
||||
|
||||
<dynamicField name="*_booldv" type="boolean" indexed="false" stored="false" docValues="true"/>
|
||||
<dynamicField name="*_booldv_missingfirst" type="boolean" indexed="false" stored="false" docValues="true"
|
||||
sortMissingFirst="true"/>
|
||||
<dynamicField name="*_booldv_missinglast" type="boolean" indexed="false" stored="false" docValues="true"
|
||||
sortMissingLast="true"/>
|
||||
|
||||
<uniqueKey>id</uniqueKey>
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
<field name="datedv" type="date" indexed="false" stored="false" docValues="true" multiValued="true"/>
|
||||
|
||||
<field name="stringdv" type="string" indexed="false" stored="false" docValues="true" multiValued="true"/>
|
||||
<field name="booldv" type="boolean" indexed="false" stored="false" docValues="true" multiValued="true"/>
|
||||
|
||||
<uniqueKey>id</uniqueKey>
|
||||
|
||||
|
|
|
@ -452,6 +452,7 @@
|
|||
<field name="bind" type="boolean" indexed="true" stored="false"/>
|
||||
<field name="bsto" type="boolean" indexed="false" stored="true"/>
|
||||
<field name="bindsto" type="boolean" indexed="true" stored="true"/>
|
||||
<field name="bindstom" type="boolean" indexed="true" stored="true" multiValued="true"/>
|
||||
<field name="isto" type="int" indexed="false" stored="true"/>
|
||||
<field name="iind" type="int" indexed="true" stored="false"/>
|
||||
<field name="ssto" type="string" indexed="false" stored="true"/>
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.solr.schema;
|
|||
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests things like sorting on docvalues with missing values
|
||||
|
@ -123,239 +124,290 @@ public class DocValuesMissingTest extends SolrTestCaseJ4 {
|
|||
}
|
||||
|
||||
/** float with default lucene sort (treats as 0) */
|
||||
@Test
|
||||
public void testFloatSort() throws Exception {
|
||||
checkSortMissingDefault("floatdv", "-1.3", "4.2");
|
||||
}
|
||||
/** dynamic float with default lucene sort (treats as 0) */
|
||||
@Test
|
||||
public void testDynFloatSort() throws Exception {
|
||||
checkSortMissingDefault("dyn_floatdv", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** float with sort missing always first */
|
||||
@Test
|
||||
public void testFloatSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("floatdv_missingfirst", "-1.3", "4.2");
|
||||
}
|
||||
/** dynamic float with sort missing always first */
|
||||
@Test
|
||||
public void testDynFloatSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("dyn_floatdv_missingfirst", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** float with sort missing always last */
|
||||
@Test
|
||||
public void testFloatSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("floatdv_missinglast", "-1.3", "4.2");
|
||||
}
|
||||
/** dynamic float with sort missing always last */
|
||||
@Test
|
||||
public void testDynFloatSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("dyn_floatdv_missinglast", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** float function query based on missing */
|
||||
@Test
|
||||
public void testFloatMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("floatdv", "-1.3", "4.2");
|
||||
}
|
||||
/** dyanmic float function query based on missing */
|
||||
@Test
|
||||
public void testDynFloatMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("dyn_floatdv", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** float missing facet count */
|
||||
@Test
|
||||
public void testFloatMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("floatdv", "-1.3", "4.2");
|
||||
}
|
||||
/** dynamic float missing facet count */
|
||||
@Test
|
||||
public void testDynFloatMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("dyn_floatdv", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** int with default lucene sort (treats as 0) */
|
||||
@Test
|
||||
public void testIntSort() throws Exception {
|
||||
checkSortMissingDefault("intdv", "-1", "4");
|
||||
}
|
||||
/** dynamic int with default lucene sort (treats as 0) */
|
||||
@Test
|
||||
public void testDynIntSort() throws Exception {
|
||||
checkSortMissingDefault("dyn_intdv", "-1", "4");
|
||||
}
|
||||
|
||||
/** int with sort missing always first */
|
||||
@Test
|
||||
public void testIntSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("intdv_missingfirst", "-1", "4");
|
||||
}
|
||||
/** dynamic int with sort missing always first */
|
||||
@Test
|
||||
public void testDynIntSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("dyn_intdv_missingfirst", "-1", "4");
|
||||
}
|
||||
|
||||
/** int with sort missing always last */
|
||||
@Test
|
||||
public void testIntSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("intdv_missinglast", "-1", "4");
|
||||
}
|
||||
/** dynamic int with sort missing always last */
|
||||
@Test
|
||||
public void testDynIntSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("dyn_intdv_missinglast", "-1", "4");
|
||||
}
|
||||
|
||||
/** int function query based on missing */
|
||||
@Test
|
||||
public void testIntMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("intdv", "-1", "4");
|
||||
}
|
||||
/** dynamic int function query based on missing */
|
||||
@Test
|
||||
public void testDynIntMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("dyn_intdv", "-1", "4");
|
||||
}
|
||||
|
||||
/** int missing facet count */
|
||||
@Test
|
||||
public void testIntMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("intdv", "-1", "4");
|
||||
}
|
||||
/** dynamic int missing facet count */
|
||||
@Test
|
||||
public void testDynIntMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("dyn_intdv", "-1", "4");
|
||||
}
|
||||
|
||||
/** double with default lucene sort (treats as 0) */
|
||||
@Test
|
||||
public void testDoubleSort() throws Exception {
|
||||
checkSortMissingDefault("doubledv", "-1.3", "4.2");
|
||||
}
|
||||
/** dynamic double with default lucene sort (treats as 0) */
|
||||
@Test
|
||||
public void testDynDoubleSort() throws Exception {
|
||||
checkSortMissingDefault("dyn_doubledv", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** double with sort missing always first */
|
||||
@Test
|
||||
public void testDoubleSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("doubledv_missingfirst", "-1.3", "4.2");
|
||||
}
|
||||
/** dynamic double with sort missing always first */
|
||||
@Test
|
||||
public void testDynDoubleSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("dyn_doubledv_missingfirst", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** double with sort missing always last */
|
||||
@Test
|
||||
public void testDoubleSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("doubledv_missinglast", "-1.3", "4.2");
|
||||
}
|
||||
/** dynamic double with sort missing always last */
|
||||
@Test
|
||||
public void testDynDoubleSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("dyn_doubledv_missinglast", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** double function query based on missing */
|
||||
@Test
|
||||
public void testDoubleMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("doubledv", "-1.3", "4.2");
|
||||
}
|
||||
/** dyanmic double function query based on missing */
|
||||
@Test
|
||||
public void testDynDoubleMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("dyn_doubledv", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** double missing facet count */
|
||||
@Test
|
||||
public void testDoubleMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("doubledv", "-1.3", "4.2");
|
||||
}
|
||||
/** dynamic double missing facet count */
|
||||
@Test
|
||||
public void testDynDoubleMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("dyn_doubledv", "-1.3", "4.2");
|
||||
}
|
||||
|
||||
/** long with default lucene sort (treats as 0) */
|
||||
@Test
|
||||
public void testLongSort() throws Exception {
|
||||
checkSortMissingDefault("longdv", "-1", "4");
|
||||
}
|
||||
/** dynamic long with default lucene sort (treats as 0) */
|
||||
@Test
|
||||
public void testDynLongSort() throws Exception {
|
||||
checkSortMissingDefault("dyn_longdv", "-1", "4");
|
||||
}
|
||||
|
||||
/** long with sort missing always first */
|
||||
@Test
|
||||
public void testLongSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("longdv_missingfirst", "-1", "4");
|
||||
}
|
||||
/** dynamic long with sort missing always first */
|
||||
@Test
|
||||
public void testDynLongSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("dyn_longdv_missingfirst", "-1", "4");
|
||||
}
|
||||
|
||||
/** long with sort missing always last */
|
||||
@Test
|
||||
public void testLongSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("longdv_missinglast", "-1", "4");
|
||||
}
|
||||
/** dynamic long with sort missing always last */
|
||||
@Test
|
||||
public void testDynLongSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("dyn_longdv_missinglast", "-1", "4");
|
||||
}
|
||||
|
||||
/** long function query based on missing */
|
||||
@Test
|
||||
public void testLongMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("longdv", "-1", "4");
|
||||
}
|
||||
/** dynamic long function query based on missing */
|
||||
@Test
|
||||
public void testDynLongMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("dyn_longdv", "-1", "4");
|
||||
}
|
||||
|
||||
/** long missing facet count */
|
||||
@Test
|
||||
public void testLongMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("longdv", "-1", "4");
|
||||
}
|
||||
/** dynamic long missing facet count */
|
||||
@Test
|
||||
public void testDynLongMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("dyn_longdv", "-1", "4");
|
||||
}
|
||||
|
||||
/** date with default lucene sort (treats as 1970) */
|
||||
@Test
|
||||
public void testDateSort() throws Exception {
|
||||
checkSortMissingDefault("datedv", "1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
/** dynamic date with default lucene sort (treats as 1970) */
|
||||
@Test
|
||||
public void testDynDateSort() throws Exception {
|
||||
checkSortMissingDefault("dyn_datedv", "1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
|
||||
/** date with sort missing always first */
|
||||
@Test
|
||||
public void testDateSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("datedv_missingfirst",
|
||||
"1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
/** dynamic date with sort missing always first */
|
||||
@Test
|
||||
public void testDynDateSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("dyn_datedv_missingfirst",
|
||||
"1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
|
||||
/** date with sort missing always last */
|
||||
@Test
|
||||
public void testDateSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("datedv_missinglast",
|
||||
"1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
/** dynamic date with sort missing always last */
|
||||
@Test
|
||||
public void testDynDateSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("dyn_datedv_missinglast",
|
||||
"1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
|
||||
/** date function query based on missing */
|
||||
@Test
|
||||
public void testDateMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("datedv",
|
||||
"1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
/** dynamic date function query based on missing */
|
||||
@Test
|
||||
public void testDynDateMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("dyn_datedv",
|
||||
"1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
|
||||
/** date missing facet count */
|
||||
@Test
|
||||
public void testDateMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("datedv",
|
||||
"1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
/** dynamic date missing facet count */
|
||||
@Test
|
||||
public void testDynDateMissingFacet() throws Exception {
|
||||
checkSortMissingFacet("dyn_datedv",
|
||||
"1900-12-31T23:59:59.999Z", "2005-12-31T23:59:59.999Z");
|
||||
}
|
||||
|
||||
/** string (and dynamic string) with default lucene sort (treats as "") */
|
||||
@Test
|
||||
public void testStringSort() throws Exception {
|
||||
|
||||
// note: cant use checkSortMissingDefault because
|
||||
|
@ -377,33 +429,40 @@ public class DocValuesMissingTest extends SolrTestCaseJ4 {
|
|||
}
|
||||
|
||||
/** string with sort missing always first */
|
||||
@Test
|
||||
public void testStringSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("stringdv_missingfirst", "a", "z");
|
||||
}
|
||||
/** dynamic string with sort missing always first */
|
||||
@Test
|
||||
public void testDynStringSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("dyn_stringdv_missingfirst", "a", "z");
|
||||
}
|
||||
|
||||
/** string with sort missing always last */
|
||||
@Test
|
||||
public void testStringSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("stringdv_missinglast", "a", "z");
|
||||
}
|
||||
/** dynamic string with sort missing always last */
|
||||
@Test
|
||||
public void testDynStringSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("dyn_stringdv_missinglast", "a", "z");
|
||||
}
|
||||
|
||||
/** string function query based on missing */
|
||||
@Test
|
||||
public void testStringMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("stringdv", "a", "z");
|
||||
}
|
||||
/** dynamic string function query based on missing */
|
||||
@Test
|
||||
public void testDynStringMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("dyn_stringdv", "a", "z");
|
||||
}
|
||||
|
||||
/** string missing facet count */
|
||||
@Test
|
||||
public void testStringMissingFacet() throws Exception {
|
||||
assertU(adoc("id", "0")); // missing
|
||||
assertU(adoc("id", "1")); // missing
|
||||
|
@ -415,4 +474,74 @@ public class DocValuesMissingTest extends SolrTestCaseJ4 {
|
|||
"//lst[@name='facet_fields']/lst[@name='stringdv']/int[@name='z'][.=1]",
|
||||
"//lst[@name='facet_fields']/lst[@name='stringdv']/int[.=2]");
|
||||
}
|
||||
|
||||
/** bool (and dynamic bool) with default lucene sort (treats as "") */
|
||||
@Test
|
||||
public void testBoolSort() throws Exception {
|
||||
// note: cant use checkSortMissingDefault because
|
||||
// nothing sorts lower then the default of "" and
|
||||
// bool fields are, at root, string fields.
|
||||
for (String field : new String[] {"booldv","dyn_booldv"}) {
|
||||
assertU(adoc("id", "0")); // missing
|
||||
assertU(adoc("id", "1", field, "false"));
|
||||
assertU(adoc("id", "2", field, "true"));
|
||||
assertU(commit());
|
||||
assertQ(req("q", "*:*", "sort", field+" asc"),
|
||||
"//result/doc[1]/str[@name='id'][.=0]",
|
||||
"//result/doc[2]/str[@name='id'][.=1]",
|
||||
"//result/doc[3]/str[@name='id'][.=2]");
|
||||
assertQ(req("q", "*:*", "sort", field+" desc"),
|
||||
"//result/doc[1]/str[@name='id'][.=2]",
|
||||
"//result/doc[2]/str[@name='id'][.=1]",
|
||||
"//result/doc[3]/str[@name='id'][.=0]");
|
||||
}
|
||||
}
|
||||
|
||||
/** bool with sort missing always first */
|
||||
@Test
|
||||
public void testBoolSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("booldv_missingfirst", "false", "ture");
|
||||
}
|
||||
/** dynamic bool with sort missing always first */
|
||||
@Test
|
||||
public void testDynBoolSortMissingFirst() throws Exception {
|
||||
checkSortMissingFirst("dyn_booldv_missingfirst", "false", "true");
|
||||
}
|
||||
|
||||
/** bool with sort missing always last */
|
||||
@Test
|
||||
public void testBoolSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("booldv_missinglast", "false", "true");
|
||||
}
|
||||
/** dynamic bool with sort missing always last */
|
||||
@Test
|
||||
public void testDynBoolSortMissingLast() throws Exception {
|
||||
checkSortMissingLast("dyn_booldv_missinglast", "false", "true");
|
||||
}
|
||||
|
||||
/** bool function query based on missing */
|
||||
@Test
|
||||
public void testBoolMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("booldv", "false", "true");
|
||||
}
|
||||
/** dynamic bool function query based on missing */
|
||||
@Test
|
||||
public void testDynBoolMissingFunction() throws Exception {
|
||||
checkSortMissingFunction("dyn_booldv", "false", "true");
|
||||
}
|
||||
|
||||
/** bool missing facet count */
|
||||
@Test
|
||||
public void testBoolMissingFacet() throws Exception {
|
||||
assertU(adoc("id", "0")); // missing
|
||||
assertU(adoc("id", "1")); // missing
|
||||
assertU(adoc("id", "2", "booldv", "false"));
|
||||
assertU(adoc("id", "3", "booldv", "true"));
|
||||
assertU(commit());
|
||||
assertQ(req("q", "*:*", "facet", "true", "facet.field", "booldv", "facet.mincount", "1", "facet.missing", "true"),
|
||||
"//lst[@name='facet_fields']/lst[@name='booldv']/int[@name='false'][.=1]",
|
||||
"//lst[@name='facet_fields']/lst[@name='booldv']/int[@name='true'][.=1]",
|
||||
"//lst[@name='facet_fields']/lst[@name='booldv']/int[.=2]");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.solr.core.SolrCore;
|
|||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.util.RefCounted;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -36,7 +37,7 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
|
||||
// sanity check our schema meets our expectations
|
||||
final IndexSchema schema = h.getCore().getLatestSchema();
|
||||
for (String f : new String[] {"floatdv", "intdv", "doubledv", "longdv", "datedv", "stringdv"}) {
|
||||
for (String f : new String[] {"floatdv", "intdv", "doubledv", "longdv", "datedv", "stringdv", "booldv"}) {
|
||||
final SchemaField sf = schema.getField(f);
|
||||
assertTrue(f + " is not multiValued, test is useless, who changed the schema?",
|
||||
sf.multiValued());
|
||||
|
@ -52,8 +53,11 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
assertU(delQ("*:*"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocValues() throws IOException {
|
||||
assertU(adoc("id", "1", "floatdv", "4.5", "intdv", "-1", "intdv", "3", "stringdv", "value1", "stringdv", "value2"));
|
||||
assertU(adoc("id", "1", "floatdv", "4.5", "intdv", "-1", "intdv", "3",
|
||||
"stringdv", "value1", "stringdv", "value2",
|
||||
"booldv", "false", "booldv", "true"));
|
||||
assertU(commit());
|
||||
try (SolrCore core = h.getCoreInc()) {
|
||||
final RefCounted<SolrIndexSearcher> searcherRef = core.openNewSearcher(true, true);
|
||||
|
@ -63,6 +67,7 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
assertEquals(1, reader.numDocs());
|
||||
final FieldInfos infos = reader.getFieldInfos();
|
||||
assertEquals(DocValuesType.SORTED_SET, infos.fieldInfo("stringdv").getDocValuesType());
|
||||
assertEquals(DocValuesType.SORTED_SET, infos.fieldInfo("booldv").getDocValuesType());
|
||||
assertEquals(DocValuesType.SORTED_SET, infos.fieldInfo("floatdv").getDocValuesType());
|
||||
assertEquals(DocValuesType.SORTED_SET, infos.fieldInfo("intdv").getDocValuesType());
|
||||
|
||||
|
@ -71,6 +76,14 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
assertEquals(0, dv.nextOrd());
|
||||
assertEquals(1, dv.nextOrd());
|
||||
assertEquals(SortedSetDocValues.NO_MORE_ORDS, dv.nextOrd());
|
||||
|
||||
dv = reader.getSortedSetDocValues("booldv");
|
||||
dv.setDocument(0);
|
||||
assertEquals(0, dv.nextOrd());
|
||||
assertEquals(1, dv.nextOrd());
|
||||
assertEquals(SortedSetDocValues.NO_MORE_ORDS, dv.nextOrd());
|
||||
|
||||
|
||||
} finally {
|
||||
searcherRef.decref();
|
||||
}
|
||||
|
@ -80,6 +93,7 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
/** Tests the ability to do basic queries (without scoring, just match-only) on
|
||||
* string docvalues fields that are not inverted (indexed "forward" only)
|
||||
*/
|
||||
@Test
|
||||
public void testStringDocValuesMatch() throws Exception {
|
||||
assertU(adoc("id", "1", "stringdv", "b"));
|
||||
assertU(adoc("id", "2", "stringdv", "a"));
|
||||
|
@ -123,10 +137,49 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
"//result/doc[1]/str[@name='id'][.=4]"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/** Tests the ability to do basic queries (without scoring, just match-only) on
|
||||
* boolean docvalues fields that are not inverted (indexed "forward" only)
|
||||
*/
|
||||
@Test
|
||||
public void testBoolDocValuesMatch() throws Exception {
|
||||
assertU(adoc("id", "1", "booldv", "true"));
|
||||
assertU(adoc("id", "2", "booldv", "false"));
|
||||
assertU(adoc("id", "3", "booldv", "true"));
|
||||
assertU(adoc("id", "4", "booldv", "false"));
|
||||
assertU(adoc("id", "5", "booldv", "true", "booldv", "false"));
|
||||
assertU(commit());
|
||||
|
||||
// string: termquery
|
||||
assertQ(req("q", "booldv:true", "sort", "id asc"),
|
||||
"//*[@numFound='3']",
|
||||
"//result/doc[1]/str[@name='id'][.=1]",
|
||||
"//result/doc[2]/str[@name='id'][.=3]",
|
||||
"//result/doc[3]/str[@name='id'][.=5]"
|
||||
);
|
||||
|
||||
// boolean: range query,
|
||||
assertQ(req("q", "booldv:[false TO false]", "sort", "id asc"),
|
||||
"//*[@numFound='3']",
|
||||
"//result/doc[1]/str[@name='id'][.=2]",
|
||||
"//result/doc[2]/str[@name='id'][.=4]",
|
||||
"//result/doc[3]/str[@name='id'][.=5]");
|
||||
|
||||
|
||||
assertQ(req("q", "*:*", "sort", "id asc", "rows", "10", "fl", "booldv"),
|
||||
"//result/doc[1]/arr[@name='booldv']/bool[1][.='true']",
|
||||
"//result/doc[2]/arr[@name='booldv']/bool[1][.='false']",
|
||||
"//result/doc[3]/arr[@name='booldv']/bool[1][.='true']",
|
||||
"//result/doc[4]/arr[@name='booldv']/bool[1][.='false']",
|
||||
"//result/doc[5]/arr[@name='booldv']/bool[1][.='false']",
|
||||
"//result/doc[5]/arr[@name='booldv']/bool[2][.='true']"
|
||||
);
|
||||
|
||||
}
|
||||
/** Tests the ability to do basic queries (without scoring, just match-only) on
|
||||
* float docvalues fields that are not inverted (indexed "forward" only)
|
||||
*/
|
||||
@Test
|
||||
public void testFloatDocValuesMatch() throws Exception {
|
||||
assertU(adoc("id", "1", "floatdv", "2"));
|
||||
assertU(adoc("id", "2", "floatdv", "-5"));
|
||||
|
@ -166,6 +219,7 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
/** Tests the ability to do basic queries (without scoring, just match-only) on
|
||||
* double docvalues fields that are not inverted (indexed "forward" only)
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleDocValuesMatch() throws Exception {
|
||||
assertU(adoc("id", "1", "doubledv", "2"));
|
||||
assertU(adoc("id", "2", "doubledv", "-5"));
|
||||
|
@ -201,17 +255,34 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
"//result/doc[1]/str[@name='id'][.=2]"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocValuesFacetingSimple() {
|
||||
// this is the random test verbatim from DocValuesTest, so it populates with the default values defined in its schema.
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
assertU(adoc("id", "" + i, "floatdv", "1", "intdv", "2", "doubledv", "3", "longdv", "4", "datedv", "1995-12-31T23:59:59.999Z"));
|
||||
assertU(adoc("id", "" + i, "floatdv", "1", "intdv", "2", "doubledv", "3", "longdv", "4",
|
||||
"datedv", "1995-12-31T23:59:59.999Z",
|
||||
"stringdv", "abc", "booldv", "true"));
|
||||
}
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
if (rarely()) {
|
||||
assertU(commit()); // to have several segments
|
||||
}
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i, "intdv", "" + i, "doubledv", "" + i, "longdv", "" + i, "datedv", (1900+i) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i));
|
||||
switch (i % 3) {
|
||||
case 0:
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i, "intdv", "" + i, "doubledv", "" + i, "longdv", "" + i,
|
||||
"datedv", (1900+i) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i, "booldv", "true", "booldv", "true"));
|
||||
break;
|
||||
case 1:
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i, "intdv", "" + i, "doubledv", "" + i, "longdv", "" + i,
|
||||
"datedv", (1900+i) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i, "booldv", "false", "booldv", "false"));
|
||||
break;
|
||||
case 2:
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i, "intdv", "" + i, "doubledv", "" + i, "longdv", "" + i,
|
||||
"datedv", (1900+i) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i, "booldv", "true", "booldv", "false"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
assertU(commit());
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "longdv", "facet.sort", "count", "facet.limit", "1"),
|
||||
|
@ -248,5 +319,25 @@ public class DocValuesMultiTest extends SolrTestCaseJ4 {
|
|||
"//lst[@name='datedv']/int[@name='1900-12-31T23:59:59.999Z'][.='1']");
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "datedv", "facet.sort", "index", "facet.offset", "33", "facet.limit", "1", "facet.mincount", "1"),
|
||||
"//lst[@name='datedv']/int[@name='1933-12-31T23:59:59.999Z'][.='1']");
|
||||
|
||||
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "stringdv", "facet.sort", "count", "facet.limit", "1"),
|
||||
"//lst[@name='stringdv']/int[@name='abc'][.='50']");
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "stringdv", "facet.sort", "count", "facet.offset", "1", "facet.limit", "-1", "facet.mincount", "1"),
|
||||
"//lst[@name='stringdv']/int[@name='abc1'][.='1']",
|
||||
"//lst[@name='stringdv']/int[@name='abc13'][.='1']",
|
||||
"//lst[@name='stringdv']/int[@name='abc19'][.='1']",
|
||||
"//lst[@name='stringdv']/int[@name='abc49'][.='1']"
|
||||
);
|
||||
|
||||
// Even though offseting by 33, the sort order is abc1 abc11....abc2 so it throws the position in the return list off.
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "stringdv", "facet.sort", "index", "facet.offset", "33", "facet.limit", "1", "facet.mincount", "1"),
|
||||
"//lst[@name='stringdv']/int[@name='abc38'][.='1']");
|
||||
|
||||
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "booldv", "facet.sort", "count"),
|
||||
"//lst[@name='booldv']/int[@name='true'][.='83']",
|
||||
"//lst[@name='booldv']/int[@name='false'][.='33']");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.solr.core.SolrCore;
|
|||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.util.RefCounted;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -49,7 +50,7 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
|
||||
// sanity check our schema meets our expectations
|
||||
final IndexSchema schema = h.getCore().getLatestSchema();
|
||||
for (String f : new String[] {"floatdv", "intdv", "doubledv", "longdv", "datedv", "stringdv"}) {
|
||||
for (String f : new String[] {"floatdv", "intdv", "doubledv", "longdv", "datedv", "stringdv", "booldv"}) {
|
||||
final SchemaField sf = schema.getField(f);
|
||||
assertFalse(f + " is multiValued, test is useless, who changed the schema?",
|
||||
sf.multiValued());
|
||||
|
@ -65,6 +66,7 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
assertU(delQ("*:*"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocValues() throws IOException {
|
||||
assertU(adoc("id", "1"));
|
||||
assertU(commit());
|
||||
|
@ -80,17 +82,21 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
assertEquals(DocValuesType.NUMERIC, infos.fieldInfo("doubledv").getDocValuesType());
|
||||
assertEquals(DocValuesType.NUMERIC, infos.fieldInfo("longdv").getDocValuesType());
|
||||
assertEquals(DocValuesType.SORTED, infos.fieldInfo("stringdv").getDocValuesType());
|
||||
assertEquals(DocValuesType.SORTED, infos.fieldInfo("booldv").getDocValuesType());
|
||||
|
||||
assertEquals((long) Float.floatToIntBits(1), reader.getNumericDocValues("floatdv").get(0));
|
||||
assertEquals(2L, reader.getNumericDocValues("intdv").get(0));
|
||||
assertEquals(Double.doubleToLongBits(3), reader.getNumericDocValues("doubledv").get(0));
|
||||
assertEquals(4L, reader.getNumericDocValues("longdv").get(0));
|
||||
assertEquals("solr", reader.getSortedDocValues("stringdv").get(0).utf8ToString());
|
||||
assertEquals("T", reader.getSortedDocValues("booldv").get(0).utf8ToString());
|
||||
|
||||
final IndexSchema schema = core.getLatestSchema();
|
||||
final SchemaField floatDv = schema.getField("floatdv");
|
||||
final SchemaField intDv = schema.getField("intdv");
|
||||
final SchemaField doubleDv = schema.getField("doubledv");
|
||||
final SchemaField longDv = schema.getField("longdv");
|
||||
final SchemaField boolDv = schema.getField("booldv");
|
||||
|
||||
FunctionValues values = floatDv.getType().getValueSource(floatDv, null).getValues(null, searcher.getLeafReader().leaves().get(0));
|
||||
assertEquals(1f, values.floatVal(0), 0f);
|
||||
|
@ -104,6 +110,10 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
values = longDv.getType().getValueSource(longDv, null).getValues(null, searcher.getLeafReader().leaves().get(0));
|
||||
assertEquals(4L, values.longVal(0));
|
||||
assertEquals(4L, values.objectVal(0));
|
||||
|
||||
values = boolDv.getType().getValueSource(boolDv, null).getValues(null, searcher.getLeafReader().leaves().get(0));
|
||||
assertEquals("true", values.strVal(0));
|
||||
assertEquals(true, values.objectVal(0));
|
||||
|
||||
// check reversibility of created fields
|
||||
tstToObj(schema.getField("floatdv"), -1.5f);
|
||||
|
@ -118,6 +128,8 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
tstToObj(schema.getField("datedvs"), new Date(1000));
|
||||
tstToObj(schema.getField("stringdv"), "foo");
|
||||
tstToObj(schema.getField("stringdvs"), "foo");
|
||||
tstToObj(schema.getField("booldv"), true);
|
||||
tstToObj(schema.getField("booldvs"), true);
|
||||
|
||||
} finally {
|
||||
searcherRef.decref();
|
||||
|
@ -132,10 +144,11 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocValuesSorting() {
|
||||
assertU(adoc("id", "1", "floatdv", "2", "intdv", "3", "doubledv", "4", "longdv", "5", "datedv", "1995-12-31T23:59:59.999Z", "stringdv", "b"));
|
||||
assertU(adoc("id", "2", "floatdv", "5", "intdv", "4", "doubledv", "3", "longdv", "2", "datedv", "1997-12-31T23:59:59.999Z", "stringdv", "a"));
|
||||
assertU(adoc("id", "3", "floatdv", "3", "intdv", "1", "doubledv", "2", "longdv", "1", "datedv", "1996-12-31T23:59:59.999Z", "stringdv", "c"));
|
||||
assertU(adoc("id", "1", "floatdv", "2", "intdv", "3", "doubledv", "4", "longdv", "5", "datedv", "1995-12-31T23:59:59.999Z", "stringdv", "b", "booldv", "true"));
|
||||
assertU(adoc("id", "2", "floatdv", "5", "intdv", "4", "doubledv", "3", "longdv", "2", "datedv", "1997-12-31T23:59:59.999Z", "stringdv", "a", "booldv", "false"));
|
||||
assertU(adoc("id", "3", "floatdv", "3", "intdv", "1", "doubledv", "2", "longdv", "1", "datedv", "1996-12-31T23:59:59.999Z", "stringdv", "c", "booldv", "true"));
|
||||
assertU(adoc("id", "4"));
|
||||
assertU(commit());
|
||||
assertQ(req("q", "*:*", "sort", "floatdv desc", "rows", "1", "fl", "id"),
|
||||
|
@ -146,8 +159,10 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
"//int[@name='id'][.='1']");
|
||||
assertQ(req("q", "*:*", "sort", "longdv desc", "rows", "1", "fl", "id"),
|
||||
"//int[@name='id'][.='1']");
|
||||
assertQ(req("q", "*:*", "sort", "datedv desc", "rows", "1", "fl", "id"),
|
||||
"//int[@name='id'][.='2']");
|
||||
assertQ(req("q", "*:*", "sort", "datedv desc", "rows", "1", "fl", "id,datedv"),
|
||||
"//int[@name='id'][.='2']",
|
||||
"//result/doc[1]/date[@name='datedv'][.='1997-12-31T23:59:59.999Z']"
|
||||
);
|
||||
assertQ(req("q", "*:*", "sort", "stringdv desc", "rows", "1", "fl", "id"),
|
||||
"//int[@name='id'][.='4']");
|
||||
assertQ(req("q", "*:*", "sort", "floatdv asc", "rows", "1", "fl", "id"),
|
||||
|
@ -162,8 +177,17 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
"//int[@name='id'][.='1']");
|
||||
assertQ(req("q", "*:*", "sort", "stringdv asc", "rows", "1", "fl", "id"),
|
||||
"//int[@name='id'][.='2']");
|
||||
assertQ(req("q", "*:*", "sort", "booldv asc", "rows", "10", "fl", "booldv,stringdv"),
|
||||
"//result/doc[1]/bool[@name='booldv'][.='false']",
|
||||
"//result/doc[2]/bool[@name='booldv'][.='true']",
|
||||
"//result/doc[3]/bool[@name='booldv'][.='true']",
|
||||
"//result/doc[4]/bool[@name='booldv'][.='true']"
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocValuesSorting2() {
|
||||
assertU(adoc("id", "1", "doubledv", "12"));
|
||||
assertU(adoc("id", "2", "doubledv", "50.567"));
|
||||
|
@ -184,6 +208,7 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocValuesFaceting() {
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
assertU(adoc("id", "" + i));
|
||||
|
@ -192,7 +217,20 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
if (rarely()) {
|
||||
assertU(commit()); // to have several segments
|
||||
}
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i, "intdv", "" + i, "doubledv", "" + i, "longdv", "" + i, "datedv", (1900+i) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i));
|
||||
switch (i % 3) {
|
||||
case 0:
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i, "intdv", "" + i, "doubledv", "" + i, "longdv", "" + i,
|
||||
"datedv", (1900 + i) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i, "booldv", "false"));
|
||||
break;
|
||||
case 1:
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i, "intdv", "" + i, "doubledv", "" + i, "longdv", "" + i,
|
||||
"datedv", (1900 + i) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i, "booldv", "true"));
|
||||
break;
|
||||
case 2:
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i, "intdv", "" + i, "doubledv", "" + i, "longdv", "" + i,
|
||||
"datedv", (1900 + i) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertU(commit());
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "longdv", "facet.sort", "count", "facet.limit", "1"),
|
||||
|
@ -229,8 +267,20 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
"//lst[@name='datedv']/int[@name='1900-12-31T23:59:59.999Z'][.='1']");
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "datedv", "facet.sort", "index", "facet.offset", "33", "facet.limit", "1", "facet.mincount", "1"),
|
||||
"//lst[@name='datedv']/int[@name='1933-12-31T23:59:59.999Z'][.='1']");
|
||||
|
||||
assertQ(req("q", "booldv:true"),
|
||||
"//*[@numFound='83']");
|
||||
|
||||
assertQ(req("q", "booldv:false"),
|
||||
"//*[@numFound='17']");
|
||||
|
||||
assertQ(req("q", "*:*", "facet", "true", "rows", "0", "facet.field", "booldv", "facet.sort", "index", "facet.mincount", "1"),
|
||||
"//lst[@name='booldv']/int[@name='false'][.='17']",
|
||||
"//lst[@name='booldv']/int[@name='true'][.='83']");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocValuesStats() {
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
assertU(adoc("id", "1000" + i, "floatdv", "" + i%2, "intdv", "" + i%3, "doubledv", "" + i%4, "longdv", "" + i%5, "datedv", (1900+i%6) + "-12-31T23:59:59.999Z", "stringdv", "abc" + i%7));
|
||||
|
@ -293,10 +343,11 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
/** Tests the ability to do basic queries (without scoring, just match-only) on
|
||||
* docvalues fields that are not inverted (indexed "forward" only)
|
||||
*/
|
||||
@Test
|
||||
public void testDocValuesMatch() throws Exception {
|
||||
assertU(adoc("id", "1", "floatdv", "2", "intdv", "3", "doubledv", "3.1", "longdv", "5", "datedv", "1995-12-31T23:59:59.999Z", "stringdv", "b"));
|
||||
assertU(adoc("id", "2", "floatdv", "-5", "intdv", "4", "doubledv", "-4.3", "longdv", "2", "datedv", "1997-12-31T23:59:59.999Z", "stringdv", "a"));
|
||||
assertU(adoc("id", "3", "floatdv", "3", "intdv", "1", "doubledv", "2.1", "longdv", "1", "datedv", "1996-12-31T23:59:59.999Z", "stringdv", "c"));
|
||||
assertU(adoc("id", "1", "floatdv", "2", "intdv", "3", "doubledv", "3.1", "longdv", "5", "datedv", "1995-12-31T23:59:59.999Z", "stringdv", "b", "booldv", "false"));
|
||||
assertU(adoc("id", "2", "floatdv", "-5", "intdv", "4", "doubledv", "-4.3", "longdv", "2", "datedv", "1997-12-31T23:59:59.999Z", "stringdv", "a", "booldv", "true"));
|
||||
assertU(adoc("id", "3", "floatdv", "3", "intdv", "1", "doubledv", "2.1", "longdv", "1", "datedv", "1996-12-31T23:59:59.999Z", "stringdv", "c", "booldv", "false"));
|
||||
assertU(adoc("id", "4", "floatdv", "3", "intdv", "-1", "doubledv", "1.5", "longdv", "1", "datedv", "1996-12-31T23:59:59.999Z", "stringdv", "car"));
|
||||
assertU(commit());
|
||||
|
||||
|
@ -439,8 +490,23 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
"//result/doc[1]/int[@name='id'][.=2]",
|
||||
"//result/doc[2]/int[@name='id'][.=4]"
|
||||
);
|
||||
// boolean basic queries:
|
||||
|
||||
assertQ(req("q", "booldv:false", "sort", "id asc"),
|
||||
"//*[@numFound='2']",
|
||||
"//result/doc[1]/int[@name='id'][.=1]",
|
||||
"//result/doc[2]/int[@name='id'][.=3]"
|
||||
);
|
||||
|
||||
assertQ(req("q", "booldv:true", "sort", "id asc"),
|
||||
"//*[@numFound='2']",
|
||||
"//result/doc[1]/int[@name='id'][.=2]",
|
||||
"//result/doc[2]/int[@name='id'][.=4]"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatAndDoubleRangeQueryRandom() throws Exception {
|
||||
|
||||
String fieldName[] = new String[] {"floatdv", "doubledv"};
|
||||
|
@ -556,6 +622,7 @@ public class DocValuesTest extends SolrTestCaseJ4 {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatAndDoubleRangeQuery() throws Exception {
|
||||
String fieldName[] = new String[] {"floatdv", "doubledv"};
|
||||
String largestNegative[] = new String[] {String.valueOf(0f-Float.MIN_NORMAL), String.valueOf(0f-Double.MIN_NORMAL)};
|
||||
|
|
|
@ -16,10 +16,12 @@
|
|||
*/
|
||||
package org.apache.solr.client.solrj.io;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -87,6 +89,53 @@ public class Tuple implements Cloneable {
|
|||
}
|
||||
}
|
||||
|
||||
// Convenience method since Booleans can be pased around as Strings.
|
||||
public Boolean getBool(Object key) {
|
||||
Object o = this.fields.get(key);
|
||||
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (o instanceof Boolean) {
|
||||
return (Boolean) o;
|
||||
} else {
|
||||
//Attempt to parse the Boolean
|
||||
return Boolean.parseBoolean(o.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public List<Boolean> getBools(Object key) {
|
||||
return (List<Boolean>) this.fields.get(key);
|
||||
}
|
||||
|
||||
// Convenience methods since the dates are actually shipped around as Strings.
|
||||
public Date getDate(Object key) {
|
||||
Object o = this.fields.get(key);
|
||||
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (o instanceof Date) {
|
||||
return (Date) o;
|
||||
} else {
|
||||
//Attempt to parse the Date from a String
|
||||
return new Date(Instant.parse(o.toString()).toEpochMilli());
|
||||
}
|
||||
}
|
||||
|
||||
public List<Date> getDates(Object key) {
|
||||
List<String> vals = (List<String>) this.fields.get(key);
|
||||
if (vals == null) return null;
|
||||
|
||||
List<Date> ret = new ArrayList<>();
|
||||
for (String dateStr : (List<String>) this.fields.get(key)) {
|
||||
ret.add(new Date(Instant.parse(dateStr).toEpochMilli()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Double getDouble(Object key) {
|
||||
Object o = this.fields.get(key);
|
||||
|
||||
|
@ -144,4 +193,4 @@ public class Tuple implements Cloneable {
|
|||
public void merge(Tuple other){
|
||||
fields.putAll(other.getMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -395,8 +395,19 @@
|
|||
<field name="f_multi" type="float" indexed="true" stored="true" docValues="true" multiValued="true"/>
|
||||
<field name="l_multi" type="long" indexed="true" stored="true" docValues="true" multiValued="true"/>
|
||||
<field name="d_multi" type="double" indexed="true" stored="true" docValues="true" multiValued="true"/>
|
||||
<field name="dt_multi" type="date" indexed="true" stored="true" docValues="true" multiValued="true"/>
|
||||
<field name="b_multi" type="boolean" indexed="true" stored="true" docValues="true" multiValued="true"/>
|
||||
|
||||
<field name="uuid" type="uuid" stored="true" />
|
||||
<field name="s_sing" type="string" indexed="true" stored="true" docValues="true" multiValued="false"/>
|
||||
<field name="i_sing" type="int" indexed="true" stored="true" docValues="true" multiValued="false"/>
|
||||
<field name="f_sing" type="float" indexed="true" stored="true" docValues="true" multiValued="false"/>
|
||||
<field name="l_sing" type="long" indexed="true" stored="true" docValues="true" multiValued="false"/>
|
||||
<field name="d_sing" type="double" indexed="true" stored="true" docValues="true" multiValued="false"/>
|
||||
<field name="dt_sing" type="tdate" indexed="true" stored="true" docValues="true" multiValued="false"/>
|
||||
<field name="b_sing" type="boolean" indexed="true" stored="true" docValues="true" multiValued="false"/>
|
||||
|
||||
|
||||
<field name="uuid" type="uuid" stored="true" />
|
||||
<field name="name" type="nametext" indexed="true" stored="true"/>
|
||||
<field name="text" type="text" indexed="true" stored="false"/>
|
||||
<field name="subject" type="text" indexed="true" stored="true"/>
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package org.apache.solr.client.solrj.io.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -1740,6 +1742,132 @@ public class StreamingTest extends SolrCloudTestCase {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDateBoolSorting() throws Exception {
|
||||
|
||||
new UpdateRequest()
|
||||
.add(id, "0", "b_sing", "false", "dt_sing", "1981-03-04T01:02:03.78Z")
|
||||
.add(id, "3", "b_sing", "true", "dt_sing", "1980-03-04T01:02:03.78Z")
|
||||
.add(id, "2", "b_sing", "false", "dt_sing", "1981-04-04T01:02:03.78Z")
|
||||
.add(id, "1", "b_sing", "true", "dt_sing", "1980-04-04T01:02:03.78Z")
|
||||
.add(id, "4", "b_sing", "true", "dt_sing", "1980-04-04T01:02:03.78Z")
|
||||
.commit(cluster.getSolrClient(), COLLECTION);
|
||||
|
||||
|
||||
trySortWithQt("/export");
|
||||
trySortWithQt("/select");
|
||||
}
|
||||
private void trySortWithQt(String which) throws Exception {
|
||||
//Basic CloudSolrStream Test bools desc
|
||||
|
||||
SolrParams sParams = mapParams("q", "*:*", "qt", which, "fl", "id,b_sing", "sort", "b_sing asc,id asc");
|
||||
CloudSolrStream stream = new CloudSolrStream(zkHost, COLLECTION, sParams);
|
||||
try {
|
||||
List<Tuple> tuples = getTuples(stream);
|
||||
|
||||
assert (tuples.size() == 5);
|
||||
assertOrder(tuples, 0, 2, 1, 3, 4);
|
||||
|
||||
//Basic CloudSolrStream Test bools desc
|
||||
sParams = mapParams("q", "*:*", "qt", which, "fl", "id,b_sing", "sort", "b_sing desc,id desc");
|
||||
stream = new CloudSolrStream(zkHost, COLLECTION, sParams);
|
||||
tuples = getTuples(stream);
|
||||
|
||||
assert (tuples.size() == 5);
|
||||
assertOrder(tuples, 4, 3, 1, 2, 0);
|
||||
|
||||
//Basic CloudSolrStream Test dates desc
|
||||
sParams = mapParams("q", "*:*", "qt", which, "fl", "id,dt_sing", "sort", "dt_sing desc,id asc");
|
||||
stream = new CloudSolrStream(zkHost, COLLECTION, sParams);
|
||||
tuples = getTuples(stream);
|
||||
|
||||
assert (tuples.size() == 5);
|
||||
assertOrder(tuples, 2, 0, 1, 4, 3);
|
||||
|
||||
//Basic CloudSolrStream Test ates desc
|
||||
sParams = mapParams("q", "*:*", "qt", which, "fl", "id,dt_sing", "sort", "dt_sing asc,id desc");
|
||||
stream = new CloudSolrStream(zkHost, COLLECTION, sParams);
|
||||
tuples = getTuples(stream);
|
||||
|
||||
assert (tuples.size() == 5);
|
||||
assertOrder(tuples, 3, 4, 1, 0, 2);
|
||||
} finally {
|
||||
if (stream != null) {
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllValidExportTypes() throws Exception {
|
||||
|
||||
//Test whether all the expected types are actually returned, including booleans and dates.
|
||||
// The contract is that the /select and /export handlers return the same format, so we can test this once each
|
||||
// way
|
||||
new UpdateRequest()
|
||||
.add(id, "0", "i_sing", "11", "i_multi", "12", "i_multi", "13",
|
||||
"l_sing", "14", "l_multi", "15", "l_multi", "16",
|
||||
"f_sing", "1.70", "f_multi", "1.80", "f_multi", "1.90",
|
||||
"d_sing", "1.20", "d_multi", "1.21", "d_multi", "1.22",
|
||||
"s_sing", "single", "s_multi", "sm1", "s_multi", "sm2",
|
||||
"dt_sing", "1980-01-02T11:11:33.89Z", "dt_multi", "1981-03-04T01:02:03.78Z", "dt_multi", "1981-05-24T04:05:06.99Z",
|
||||
"b_sing", "true", "b_multi", "false", "b_multi", "true"
|
||||
)
|
||||
.commit(cluster.getSolrClient(), COLLECTION);
|
||||
|
||||
tryWithQt("/export");
|
||||
tryWithQt("/select");
|
||||
}
|
||||
|
||||
// We should be getting the exact same thing back with both the export and select handlers, so test
|
||||
private void tryWithQt(String which) throws IOException {
|
||||
SolrParams sParams = StreamingTest.mapParams("q", "*:*", "qt", which, "fl",
|
||||
"id,i_sing,i_multi,l_sing,l_multi,f_sing,f_multi,d_sing,d_multi,dt_sing,dt_multi,s_sing,s_multi,b_sing,b_multi",
|
||||
"sort", "i_sing asc");
|
||||
try (CloudSolrStream stream = new CloudSolrStream(zkHost, COLLECTION, sParams)) {
|
||||
|
||||
Tuple tuple = getTuple(stream); // All I really care about is that all the fields are returned. There's
|
||||
|
||||
assertTrue("Integers should be returned", tuple.getLong("i_sing") == 11L);
|
||||
assertTrue("MV should be returned for i_multi", tuple.getLongs("i_multi").get(0) == 12);
|
||||
assertTrue("MV should be returned for i_multi", tuple.getLongs("i_multi").get(1) == 13);
|
||||
|
||||
assertTrue("longs should be returned", tuple.getLong("l_sing") == 14L);
|
||||
assertTrue("MV should be returned for l_multi", tuple.getLongs("l_multi").get(0) == 15);
|
||||
assertTrue("MV should be returned for l_multi", tuple.getLongs("l_multi").get(1) == 16);
|
||||
|
||||
assertTrue("floats should be returned", tuple.getDouble("f_sing") == 1.7);
|
||||
assertTrue("MV should be returned for f_multi", tuple.getDoubles("f_multi").get(0) == 1.8);
|
||||
assertTrue("MV should be returned for f_multi", tuple.getDoubles("f_multi").get(1) == 1.9);
|
||||
|
||||
assertTrue("doubles should be returned", tuple.getDouble("d_sing") == 1.2);
|
||||
assertTrue("MV should be returned for d_multi", tuple.getDoubles("d_multi").get(0) == 1.21);
|
||||
assertTrue("MV should be returned for d_multi", tuple.getDoubles("d_multi").get(1) == 1.22);
|
||||
|
||||
assertTrue("Strings should be returned", tuple.getString("s_sing").equals("single"));
|
||||
assertTrue("MV should be returned for s_multi", tuple.getStrings("s_multi").get(0).equals("sm1"));
|
||||
assertTrue("MV should be returned for s_multi", tuple.getStrings("s_multi").get(1).equals("sm2"));
|
||||
|
||||
assertTrue("Dates should be returned as Strings", tuple.getString("dt_sing").equals("1980-01-02T11:11:33.890Z"));
|
||||
assertTrue("MV dates should be returned as Strings for dt_multi", tuple.getStrings("dt_multi").get(0).equals("1981-03-04T01:02:03.780Z"));
|
||||
assertTrue("MV dates should be returned as Strings for dt_multi", tuple.getStrings("dt_multi").get(1).equals("1981-05-24T04:05:06.990Z"));
|
||||
|
||||
// Also test native type conversion
|
||||
Date dt = new Date(Instant.parse("1980-01-02T11:11:33.890Z").toEpochMilli());
|
||||
assertTrue("Dates should be returned as Dates", tuple.getDate("dt_sing").equals(dt));
|
||||
dt = new Date(Instant.parse("1981-03-04T01:02:03.780Z").toEpochMilli());
|
||||
assertTrue("MV dates should be returned as Dates for dt_multi", tuple.getDates("dt_multi").get(0).equals(dt));
|
||||
dt = new Date(Instant.parse("1981-05-24T04:05:06.990Z").toEpochMilli());
|
||||
assertTrue("MV dates should be returned as Dates for dt_multi", tuple.getDates("dt_multi").get(1).equals(dt));
|
||||
|
||||
assertTrue("Booleans should be returned", tuple.getBool("b_sing"));
|
||||
assertFalse("MV boolean should be returned for b_multi", tuple.getBools("b_multi").get(0));
|
||||
assertTrue("MV boolean should be returned for b_multi", tuple.getBools("b_multi").get(1));
|
||||
}
|
||||
|
||||
}
|
||||
protected List<Tuple> getTuples(TupleStream tupleStream) throws IOException {
|
||||
tupleStream.open();
|
||||
List<Tuple> tuples = new ArrayList();
|
||||
|
|
Loading…
Reference in New Issue