Adding date tests to SOLR-2134

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1201484 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Erick Erickson 2011-11-13 19:29:17 +00:00
parent dbd48a72e4
commit 4145656bb5
4 changed files with 130 additions and 91 deletions

View File

@ -183,6 +183,9 @@ New Features
LMDirichletSimilarity: LM with Dirichlet smoothing LMDirichletSimilarity: LM with Dirichlet smoothing
LMJelinekMercerSimilarity: LM with Jelinek-Mercer smoothing LMJelinekMercerSimilarity: LM with Jelinek-Mercer smoothing
(David Mark Nemeskey, Robert Muir) (David Mark Nemeskey, Robert Muir)
* SOLR-2134 Trie* fields should support sortMissingLast=true, and deprecate Sortable* Field Types
(Ryan McKinley, Mike McCandless, Uwe Schindler, Erick Erickson)
Optimizations Optimizations
---------------------- ----------------------

View File

@ -35,36 +35,42 @@
<fieldType name="int" class="solr.TrieIntField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/> <fieldType name="int" class="solr.TrieIntField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="float" class="solr.TrieFloatField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/> <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/> <fieldType name="long" class="solr.TrieLongField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/> <fieldType name="date" class="solr.TrieDateField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" sortMissingLast="false" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="int_last" class="solr.TrieIntField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/> <fieldType name="int_last" class="solr.TrieIntField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="float_last" class="solr.TrieFloatField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/> <fieldType name="float_last" class="solr.TrieFloatField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="long_last" class="solr.TrieLongField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/> <fieldType name="long_last" class="solr.TrieLongField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="double_last" class="solr.TrieDoubleField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/> <fieldType name="date_last" class="solr.TrieDateField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="double_last" class="solr.TrieDoubleField" precisionStep="0" sortMissingLast="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="int_first" class="solr.TrieIntField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/> <fieldType name="int_first" class="solr.TrieIntField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="float_first" class="solr.TrieFloatField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/> <fieldType name="float_first" class="solr.TrieFloatField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="long_first" class="solr.TrieLongField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/> <fieldType name="long_first" class="solr.TrieLongField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="double_first" class="solr.TrieDoubleField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/> <fieldType name="date_first" class="solr.TrieDateField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/>
<fieldType name="double_first" class="solr.TrieDoubleField" precisionStep="0" sortMissingFirst="true" omitNorms="true" positionIncrementGap="0"/>
</types> </types>
<fields> <fields>
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/> <field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="int" type="int" indexed="true" stored="true" multiValued="false"/> <field name="int" type="int" indexed="true" stored="true" multiValued="false"/>
<field name="float" type="float" indexed="true" stored="true" multiValued="false"/> <field name="float" type="float" indexed="true" stored="true" multiValued="false"/>
<field name="long" type="long" indexed="true" stored="true" multiValued="false"/> <field name="long" type="long" indexed="true" stored="true" multiValued="false"/>
<field name="date" type="date" indexed="true" stored="true" multiValued="false"/>
<field name="double" type="double" indexed="true" stored="true" multiValued="false"/> <field name="double" type="double" indexed="true" stored="true" multiValued="false"/>
<field name="int_last" type="int_last" indexed="true" stored="true" multiValued="false"/> <field name="int_last" type="int_last" indexed="true" stored="true" multiValued="false"/>
<field name="float_last" type="float_last" indexed="true" stored="true" multiValued="false"/> <field name="float_last" type="float_last" indexed="true" stored="true" multiValued="false"/>
<field name="long_last" type="long_last" indexed="true" stored="true" multiValued="false"/> <field name="long_last" type="long_last" indexed="true" stored="true" multiValued="false"/>
<field name="date_last" type="date_last" indexed="true" stored="true" multiValued="false"/>
<field name="double_last" type="double_last" indexed="true" stored="true" multiValued="false"/> <field name="double_last" type="double_last" indexed="true" stored="true" multiValued="false"/>
<field name="int_first" type="int_first" indexed="true" stored="true" multiValued="false"/> <field name="int_first" type="int_first" indexed="true" stored="true" multiValued="false"/>
<field name="float_first" type="float_first" indexed="true" stored="true" multiValued="false"/> <field name="float_first" type="float_first" indexed="true" stored="true" multiValued="false"/>
<field name="long_first" type="long_first" indexed="true" stored="true" multiValued="false"/> <field name="long_first" type="long_first" indexed="true" stored="true" multiValued="false"/>
<field name="date_first" type="date_first" indexed="true" stored="true" multiValued="false"/>
<field name="double_first" type="double_first" indexed="true" stored="true" multiValued="false"/> <field name="double_first" type="double_first" indexed="true" stored="true" multiValued="false"/>
</fields> </fields>

View File

@ -26,107 +26,133 @@ import org.junit.Test;
public class NumericFieldsTest extends SolrTestCaseJ4 { public class NumericFieldsTest extends SolrTestCaseJ4 {
@BeforeClass @BeforeClass
public static void beforeClass() throws Exception { public static void beforeClass() throws Exception {
initCore("solrconfig-master.xml","schema-numeric.xml"); initCore("solrconfig-master.xml", "schema-numeric.xml");
} }
static String[] types = new String[] { "int", "long", "float", "double" }; static String[] types = new String[]{"int", "long", "float", "double", "date"};
public static SolrInputDocument getDoc( String id, Integer number ) public static SolrInputDocument getDoc(String id, Integer number, String date) {
{
SolrInputDocument doc = new SolrInputDocument(); SolrInputDocument doc = new SolrInputDocument();
doc.addField( "id", id ); doc.addField("id", id);
for( String t : types ) { for (String t : types) {
doc.addField( t, number ); if ("date".equals(t)) {
doc.addField( t+"_last", number ); doc.addField(t, date);
doc.addField( t+"_first", number ); doc.addField(t + "_last", date);
doc.addField(t + "_first", date);
} else {
doc.addField(t, number);
doc.addField(t + "_last", number);
doc.addField(t + "_first", number);
}
} }
return doc; return doc;
} }
@Test @Test
public void testSortMissingFirstLast() public void testSortMissingFirstLast() {
{
clearIndex(); clearIndex();
assertU(adoc("id", "M1" ));
assertU(adoc( getDoc( "+4", 4 ) ));
assertU(adoc( getDoc( "+5", 5 ) ));
assertU(adoc( getDoc( "-3", -3 ) ));
assertU(adoc("id", "M2" ));
assertU(commit());
assertU(adoc("id", "M1"));
assertU(adoc(getDoc("+4", 4, "2011-04-04T00:00:00Z")));
assertU(adoc(getDoc("+5", 5, "2011-05-05T00:00:00Z")));
assertU(adoc(getDoc("-3", -3, "2011-01-01T00:00:00Z")));
assertU(adoc("id", "M2"));
assertU(commit());
// 'normal' sorting. Missing Values are 0 // 'normal' sorting. Missing Values are 0
String suffix = ""; String suffix = "";
for( String t : types ) { for (String t : types) {
assertQ( "Sorting Asc: "+t+suffix, if ("date".equals(t)) {
req("fl", "id", "q", "*:*", "sort", (t+suffix)+" asc" ), assertQ("Sorting Asc: " + t + suffix,
"//*[@numFound='5']", req("fl", "id", "q", "*:*", "sort", (t + suffix) + " asc"),
"//result/doc[1]/str[@name='id'][.='-3']", "//*[@numFound='5']",
"//result/doc[2]/str[@name='id'][.='M1']", "//result/doc[1]/str[@name='id'][.='M1']",
"//result/doc[3]/str[@name='id'][.='M2']", "//result/doc[2]/str[@name='id'][.='M2']",
"//result/doc[4]/str[@name='id'][.='+4']", "//result/doc[3]/str[@name='id'][.='-3']",
"//result/doc[5]/str[@name='id'][.='+5']" "//result/doc[4]/str[@name='id'][.='+4']",
); "//result/doc[5]/str[@name='id'][.='+5']"
);
assertQ( "Sorting Desc: "+t+suffix,
req("fl", "id", "q", "*:*", "sort", (t+suffix)+" desc" ), assertQ("Sorting Desc: " + t + suffix,
"//*[@numFound='5']", req("fl", "id", "q", "*:*", "sort", (t + suffix) + " desc"),
"//result/doc[1]/str[@name='id'][.='+5']", "//*[@numFound='5']",
"//result/doc[2]/str[@name='id'][.='+4']", "//result/doc[1]/str[@name='id'][.='+5']",
"//result/doc[3]/str[@name='id'][.='M1']", "//result/doc[2]/str[@name='id'][.='+4']",
"//result/doc[4]/str[@name='id'][.='M2']", "//result/doc[3]/str[@name='id'][.='-3']",
"//result/doc[5]/str[@name='id'][.='-3']" "//result/doc[4]/str[@name='id'][.='M1']",
); "//result/doc[5]/str[@name='id'][.='M2']"
);
} else {
assertQ("Sorting Asc: " + t + suffix,
req("fl", "id", "q", "*:*", "sort", (t + suffix) + " asc"),
"//*[@numFound='5']",
"//result/doc[1]/str[@name='id'][.='-3']",
"//result/doc[2]/str[@name='id'][.='M1']",
"//result/doc[3]/str[@name='id'][.='M2']",
"//result/doc[4]/str[@name='id'][.='+4']",
"//result/doc[5]/str[@name='id'][.='+5']"
);
assertQ("Sorting Desc: " + t + suffix,
req("fl", "id", "q", "*:*", "sort", (t + suffix) + " desc"),
"//*[@numFound='5']",
"//result/doc[1]/str[@name='id'][.='+5']",
"//result/doc[2]/str[@name='id'][.='+4']",
"//result/doc[3]/str[@name='id'][.='M1']",
"//result/doc[4]/str[@name='id'][.='M2']",
"//result/doc[5]/str[@name='id'][.='-3']"
);
}
} }
// sortMissingLast = true // sortMissingLast = true
suffix = "_last"; suffix = "_last";
for( String t : types ) { for (String t : types) {
assertQ( "Sorting Asc: "+t+suffix, assertQ("Sorting Asc: " + t + suffix,
req("fl", "id", "q", "*:*", "sort", (t+suffix)+" asc" ), req("fl", "id", "q", "*:*", "sort", (t + suffix) + " asc"),
"//*[@numFound='5']", "//*[@numFound='5']",
"//result/doc[1]/str[@name='id'][.='-3']", "//result/doc[1]/str[@name='id'][.='-3']",
"//result/doc[2]/str[@name='id'][.='+4']", "//result/doc[2]/str[@name='id'][.='+4']",
"//result/doc[3]/str[@name='id'][.='+5']", "//result/doc[3]/str[@name='id'][.='+5']",
"//result/doc[4]/str[@name='id'][.='M1']", "//result/doc[4]/str[@name='id'][.='M1']",
"//result/doc[5]/str[@name='id'][.='M2']" "//result/doc[5]/str[@name='id'][.='M2']"
); );
// This does not match // This does not match
assertQ( "Sorting Desc: "+t+suffix, assertQ("Sorting Desc: " + t + suffix,
req("fl", "id", "q", "*:*", "sort", (t+suffix)+" desc", "indent", "on" ), req("fl", "id", "q", "*:*", "sort", (t + suffix) + " desc", "indent", "on"),
"//*[@numFound='5']", "//*[@numFound='5']",
"//result/doc[1]/str[@name='id'][.='+5']", "//result/doc[1]/str[@name='id'][.='+5']",
"//result/doc[2]/str[@name='id'][.='+4']", "//result/doc[2]/str[@name='id'][.='+4']",
"//result/doc[3]/str[@name='id'][.='-3']", "//result/doc[3]/str[@name='id'][.='-3']",
"//result/doc[4]/str[@name='id'][.='M1']", "//result/doc[4]/str[@name='id'][.='M1']",
"//result/doc[5]/str[@name='id'][.='M2']" "//result/doc[5]/str[@name='id'][.='M2']"
); );
} }
// sortMissingFirst = true // sortMissingFirst = true
suffix = "_first"; suffix = "_first";
for( String t : types ) { for (String t : types) {
assertQ( "Sorting Asc: "+t+suffix, assertQ("Sorting Asc: " + t + suffix,
req("fl", "id", "q", "*:*", "sort", (t+suffix)+" asc", "indent", "on" ), req("fl", "id", "q", "*:*", "sort", (t + suffix) + " asc", "indent", "on"),
"//*[@numFound='5']", "//*[@numFound='5']",
"//result/doc[1]/str[@name='id'][.='M1']", "//result/doc[1]/str[@name='id'][.='M1']",
"//result/doc[2]/str[@name='id'][.='M2']", "//result/doc[2]/str[@name='id'][.='M2']",
"//result/doc[3]/str[@name='id'][.='-3']", "//result/doc[3]/str[@name='id'][.='-3']",
"//result/doc[4]/str[@name='id'][.='+4']", "//result/doc[4]/str[@name='id'][.='+4']",
"//result/doc[5]/str[@name='id'][.='+5']" "//result/doc[5]/str[@name='id'][.='+5']"
); );
// This does not match // This does not match
assertQ( "Sorting Desc: "+t+suffix, assertQ("Sorting Desc: " + t + suffix,
req("fl", "id", "q", "*:*", "sort", (t+suffix)+" desc", "indent", "on" ), req("fl", "id", "q", "*:*", "sort", (t + suffix) + " desc", "indent", "on"),
"//*[@numFound='5']", "//*[@numFound='5']",
"//result/doc[1]/str[@name='id'][.='M1']", "//result/doc[1]/str[@name='id'][.='M1']",
"//result/doc[2]/str[@name='id'][.='M2']", "//result/doc[2]/str[@name='id'][.='M2']",
"//result/doc[3]/str[@name='id'][.='+5']", "//result/doc[3]/str[@name='id'][.='+5']",
"//result/doc[4]/str[@name='id'][.='+4']", "//result/doc[4]/str[@name='id'][.='+4']",
"//result/doc[5]/str[@name='id'][.='-3']" "//result/doc[5]/str[@name='id'][.='-3']"
); );
} }
} }

View File

@ -74,8 +74,11 @@
<!--Binary data type. The data should be sent/retrieved in as Base64 encoded Strings --> <!--Binary data type. The data should be sent/retrieved in as Base64 encoded Strings -->
<fieldtype name="binary" class="solr.BinaryField"/> <fieldtype name="binary" class="solr.BinaryField"/>
<!-- sortMissingLast and sortMissingFirst attributes are optional attributes <!-- sortMissingLast and sortMissingFirst attributes are optional attributes are
that control how fields are sorted when values are missing. currently supported on types that are sorted internally as strings
and on numeric types.
This includes "string","boolean", and, as of 3.5 (and 4.x),
int, float, long, date, double, including the "Trie" variants.
- If sortMissingLast="true", then a sort on this field will cause documents - If sortMissingLast="true", then a sort on this field will cause documents
without the field to come after documents with the field, without the field to come after documents with the field,
regardless of the requested sort order (asc or desc). regardless of the requested sort order (asc or desc).
@ -141,7 +144,8 @@
<!-- <!--
Note: Note:
These should only be used for compatibility with existing indexes (created with lucene or older Solr versions). These should only be used for compatibility with existing indexes (created with lucene or older Solr versions).
Use Trie based fields instead. As of Solr 3.5 and 4.x, Trie based fields support sortMissingFirst/Last
Plain numeric field types that store and index the text Plain numeric field types that store and index the text
value verbatim (and hence don't correctly support range queries, since the value verbatim (and hence don't correctly support range queries, since the
lexicographic ordering isn't equal to the numeric ordering) lexicographic ordering isn't equal to the numeric ordering)