Add support for CollapseQParser with PointFields

This commit is contained in:
Cao Manh Dat 2017-03-22 15:00:33 +07:00 committed by Shalin Shekhar Mangar
parent f5f35f5dc2
commit cedf37c2fe
4 changed files with 131 additions and 131 deletions

View File

@ -114,6 +114,7 @@ New Features
* SOLR-10046: Add UninvertDocValuesMergePolicyFactory class. (Keith Laban, Christine Poerschke)
* SOLR-9994: Add support for CollapseQParser with PointFields. (Varun Thacker, Cao Manh Dat)
================== 6.5.0 ==================

View File

@ -63,6 +63,9 @@ import org.apache.solr.request.LocalSolrQueryRequest;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.FloatPointField;
import org.apache.solr.schema.IntPointField;
import org.apache.solr.schema.LongPointField;
import org.apache.solr.schema.StrField;
import org.apache.solr.schema.TrieFloatField;
import org.apache.solr.schema.TrieIntField;
@ -962,14 +965,14 @@ public class CollapsingQParserPlugin extends QParserPlugin {
} else if (funcQuery != null) {
this.collapseStrategy = new OrdValueSourceStrategy(maxDoc, nullPolicy, new int[valueCount], groupHeadSelector, this.needsScores, boostDocs, funcQuery, searcher, collapseValues);
} else {
if(fieldType instanceof TrieIntField) {
if (fieldType instanceof TrieIntField || fieldType instanceof IntPointField) {
this.collapseStrategy = new OrdIntStrategy(maxDoc, nullPolicy, new int[valueCount], groupHeadSelector, this.needsScores, boostDocs, collapseValues);
} else if(fieldType instanceof TrieFloatField) {
} else if (fieldType instanceof TrieFloatField || fieldType instanceof FloatPointField) {
this.collapseStrategy = new OrdFloatStrategy(maxDoc, nullPolicy, new int[valueCount], groupHeadSelector, this.needsScores, boostDocs, collapseValues);
} else if(fieldType instanceof TrieLongField) {
} else if (fieldType instanceof TrieLongField || fieldType instanceof LongPointField) {
this.collapseStrategy = new OrdLongStrategy(maxDoc, nullPolicy, new int[valueCount], groupHeadSelector, this.needsScores, boostDocs, collapseValues);
} else {
throw new IOException("min/max must be either TrieInt, TrieLong, TrieFloat.");
throw new IOException("min/max must be either Int/Long/Float field types");
}
}
}
@ -1146,12 +1149,12 @@ public class CollapsingQParserPlugin extends QParserPlugin {
} else if (funcQuery != null) {
this.collapseStrategy = new IntValueSourceStrategy(maxDoc, size, collapseField, nullValue, nullPolicy, groupHeadSelector, this.needsScores, boostDocsMap, funcQuery, searcher);
} else {
if(fieldType instanceof TrieIntField) {
if (fieldType instanceof TrieIntField || fieldType instanceof IntPointField) {
this.collapseStrategy = new IntIntStrategy(maxDoc, size, collapseField, nullValue, nullPolicy, groupHeadSelector, this.needsScores, boostDocsMap);
} else if(fieldType instanceof TrieFloatField) {
} else if (fieldType instanceof TrieFloatField || fieldType instanceof FloatPointField) {
this.collapseStrategy = new IntFloatStrategy(maxDoc, size, collapseField, nullValue, nullPolicy, groupHeadSelector, this.needsScores, boostDocsMap);
} else {
throw new IOException("min/max must be TrieInt or TrieFloat when collapsing on numeric fields .");
throw new IOException("min/max must be Int or Float field types when collapsing on numeric fields");
}
}
}
@ -1259,6 +1262,15 @@ public class CollapsingQParserPlugin extends QParserPlugin {
private static class CollectorFactory {
private boolean isNumericCollapsible(FieldType collapseFieldType) {
if (collapseFieldType instanceof TrieIntField || collapseFieldType instanceof IntPointField ||
collapseFieldType instanceof TrieFloatField || collapseFieldType instanceof FloatPointField) {
return true;
} else {
return false;
}
}
public DelegatingCollector getCollector(String collapseField,
GroupHeadSelector groupHeadSelector,
SortSpec sortSpec,
@ -1335,19 +1347,18 @@ public class CollapsingQParserPlugin extends QParserPlugin {
return new OrdScoreCollector(maxDoc, leafCount, docValuesProducer, nullPolicy, boostDocs);
} else if (collapseFieldType instanceof TrieIntField ||
collapseFieldType instanceof TrieFloatField) {
} else if (isNumericCollapsible(collapseFieldType)) {
int nullValue = 0;
if(collapseFieldType instanceof TrieFloatField) {
if(defaultValue != null) {
if (collapseFieldType instanceof TrieFloatField || collapseFieldType instanceof FloatPointField) {
if (defaultValue != null) {
nullValue = Float.floatToIntBits(Float.parseFloat(defaultValue));
} else {
nullValue = Float.floatToIntBits(0.0f);
}
} else {
if(defaultValue != null) {
if (defaultValue != null) {
nullValue = Integer.parseInt(defaultValue);
}
}
@ -1374,12 +1385,11 @@ public class CollapsingQParserPlugin extends QParserPlugin {
funcQuery,
searcher);
} else if((collapseFieldType instanceof TrieIntField ||
collapseFieldType instanceof TrieFloatField)) {
} else if(isNumericCollapsible(collapseFieldType)) {
int nullValue = 0;
if(collapseFieldType instanceof TrieFloatField) {
if (collapseFieldType instanceof TrieFloatField || collapseFieldType instanceof FloatPointField) {
if(defaultValue != null) {
nullValue = Float.floatToIntBits(Float.parseFloat(defaultValue));
} else {

View File

@ -16,16 +16,14 @@
*/
package org.apache.solr.search;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
@ -35,11 +33,7 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
//We want codecs that support DocValues, and ones supporting blank/empty values.
@SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42"})
@SuppressPointFields
public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig-collapseqparser.xml", "schema11.xml");
@ -56,17 +50,17 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
}
public void testMultiSort() throws Exception {
assertU(adoc("id", "1", "group_s", "group1", "test_ti", "5", "test_tl", "10"));
assertU(adoc("id", "1", "group_s", "group1", "test_i", "5", "test_l", "10"));
assertU(commit());
assertU(adoc("id", "2", "group_s", "group1", "test_ti", "5", "test_tl", "1000"));
assertU(adoc("id", "3", "group_s", "group1", "test_ti", "5", "test_tl", "1000"));
assertU(adoc("id", "4", "group_s", "group1", "test_ti", "10", "test_tl", "100"));
assertU(adoc("id", "2", "group_s", "group1", "test_i", "5", "test_l", "1000"));
assertU(adoc("id", "3", "group_s", "group1", "test_i", "5", "test_l", "1000"));
assertU(adoc("id", "4", "group_s", "group1", "test_i", "10", "test_l", "100"));
//
assertU(adoc("id", "5", "group_s", "group2", "test_ti", "5", "test_tl", "10", "term_s", "YYYY"));
assertU(adoc("id", "5", "group_s", "group2", "test_i", "5", "test_l", "10", "term_s", "YYYY"));
assertU(commit());
assertU(adoc("id", "6", "group_s", "group2", "test_ti", "5", "test_tl","1000"));
assertU(adoc("id", "7", "group_s", "group2", "test_ti", "5", "test_tl","1000", "term_s", "XXXX"));
assertU(adoc("id", "8", "group_s", "group2", "test_ti", "10","test_tl", "100"));
assertU(adoc("id", "6", "group_s", "group2", "test_i", "5", "test_l","1000"));
assertU(adoc("id", "7", "group_s", "group2", "test_i", "5", "test_l","1000", "term_s", "XXXX"));
assertU(adoc("id", "8", "group_s", "group2", "test_i", "10","test_l", "100"));
assertU(commit());
ModifiableSolrParams params;
@ -75,7 +69,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_s sort=$sort}");
params.add("sort", "test_ti asc, test_tl desc, id desc");
params.add("sort", "test_i asc, test_l desc, id desc");
assertQ(req(params)
, "*[count(//doc)=2]"
,"//result/doc[1]/float[@name='id'][.='7.0']"
@ -85,7 +79,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// group heads are selected using a complex sort, simpler sort used for final groups
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_s sort='test_ti asc, test_tl desc, id desc'}");
params.add("fq", "{!collapse field=group_s sort='test_i asc, test_l desc, id desc'}");
params.add("sort", "id asc");
assertQ(req(params)
, "*[count(//doc)=2]"
@ -96,7 +90,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// diff up the sort directions, only first clause matters with our data
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_s sort='test_ti desc, test_tl asc, id asc'}");
params.add("fq", "{!collapse field=group_s sort='test_i desc, test_l asc, id asc'}");
params.add("sort", "id desc");
assertQ(req(params)
, "*[count(//doc)=2]"
@ -107,7 +101,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// tie broken by index order
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_s sort='test_tl desc'}");
params.add("fq", "{!collapse field=group_s sort='test_l desc'}");
params.add("sort", "id desc");
assertQ(req(params)
, "*[count(//doc)=2]"
@ -118,7 +112,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// score, then tiebreakers; note top level sort by score ASCENDING (just for weirdness)
params = new ModifiableSolrParams();
params.add("q", "*:* term_s:YYYY");
params.add("fq", "{!collapse field=group_s sort='score desc, test_tl desc, test_ti asc, id asc'}");
params.add("fq", "{!collapse field=group_s sort='score desc, test_l desc, test_i asc, id asc'}");
params.add("sort", "score asc");
assertQ(req(params)
, "*[count(//doc)=2]"
@ -129,7 +123,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// score, then tiebreakers; note no score in top level sort/fl to check needsScores logic
params = new ModifiableSolrParams();
params.add("q", "*:* term_s:YYYY");
params.add("fq", "{!collapse field=group_s sort='score desc, test_tl desc, test_ti asc, id asc'}");
params.add("fq", "{!collapse field=group_s sort='score desc, test_l desc, test_i asc, id asc'}");
params.add("sort", "id desc");
assertQ(req(params)
, "*[count(//doc)=2]"
@ -140,7 +134,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// term_s desc -- term_s is missing from many docs, and uses sortMissingLast=true
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_s sort='term_s desc, test_tl asc'}");
params.add("fq", "{!collapse field=group_s sort='term_s desc, test_l asc'}");
params.add("sort", "id asc");
assertQ(req(params)
, "*[count(//doc)=2]"
@ -151,7 +145,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// term_s asc -- term_s is missing from many docs, and uses sortMissingLast=true
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_s sort='term_s asc, test_tl asc'}");
params.add("fq", "{!collapse field=group_s sort='term_s asc, test_l asc'}");
params.add("sort", "id asc");
assertQ(req(params)
, "*[count(//doc)=2]"
@ -162,7 +156,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// collapse on int field
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=test_ti sort='term_s asc, group_s asc'}");
params.add("fq", "{!collapse field=test_i sort='term_s asc, group_s asc'}");
params.add("sort", "id asc");
assertQ(req(params)
, "*[count(//doc)=2]"
@ -173,8 +167,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// collapse on term_s (very sparse) with nullPolicy=collapse
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=term_s nullPolicy=collapse sort='test_ti asc, test_tl desc, id asc'}");
params.add("sort", "test_tl asc, id asc");
params.add("fq", "{!collapse field=term_s nullPolicy=collapse sort='test_i asc, test_l desc, id asc'}");
params.add("sort", "test_l asc, id asc");
assertQ(req(params)
, "*[count(//doc)=3]"
,"//result/doc[1]/float[@name='id'][.='5.0']"
@ -185,8 +179,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// sort local param + elevation
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_s sort='term_s desc, test_tl asc'}");
params.add("sort", "test_tl asc");
params.add("fq", "{!collapse field=group_s sort='term_s desc, test_l asc'}");
params.add("sort", "test_l asc");
params.add("qt", "/elevate");
params.add("forceElevation", "true");
params.add("elevateIds", "4.0");
@ -197,8 +191,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_s sort='term_s desc, test_tl asc'}");
params.add("sort", "test_tl asc");
params.add("fq", "{!collapse field=group_s sort='term_s desc, test_l asc'}");
params.add("sort", "test_l asc");
params.add("qt", "/elevate");
params.add("forceElevation", "true");
params.add("elevateIds", "7.0");
@ -228,38 +222,38 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
@Test
public void testFieldValueCollapseWithNegativeMinMax() throws Exception {
String[] doc = {"id","1", "group_i", "-1000", "test_ti", "5", "test_tl", "-10", "test_tf", "2000.32"};
String[] doc = {"id","1", "group_i", "-1000", "test_i", "5", "test_l", "-10", "test_f", "2000.32"};
assertU(adoc(doc));
assertU(commit());
String[] doc1 = {"id","2", "group_i", "-1000", "test_ti", "50", "test_tl", "-100", "test_tf", "2000.33"};
String[] doc1 = {"id","2", "group_i", "-1000", "test_i", "50", "test_l", "-100", "test_f", "2000.33"};
assertU(adoc(doc1));
String[] doc2 = {"id","3", "group_i", "-1000", "test_tl", "100", "test_tf", "200"};
String[] doc2 = {"id","3", "group_i", "-1000", "test_l", "100", "test_f", "200"};
assertU(adoc(doc2));
assertU(commit());
String[] doc3 = {"id","4", "test_ti", "500", "test_tl", "1000", "test_tf", "2000"};
String[] doc3 = {"id","4", "test_i", "500", "test_l", "1000", "test_f", "2000"};
assertU(adoc(doc3));
String[] doc4 = {"id","5", "group_i", "-1000", "test_ti", "4", "test_tl", "10", "test_tf", "2000.31"};
String[] doc4 = {"id","5", "group_i", "-1000", "test_i", "4", "test_l", "10", "test_f", "2000.31"};
assertU(adoc(doc4));
assertU(commit());
String[] doc5 = {"id","6", "group_i", "-1000", "test_ti", "10", "test_tl", "100", "test_tf", "-2000.12"};
String[] doc5 = {"id","6", "group_i", "-1000", "test_i", "10", "test_l", "100", "test_f", "-2000.12"};
assertU(adoc(doc5));
assertU(commit());
String[] doc6 = {"id","7", "group_i", "-1000", "test_ti", "8", "test_tl", "-50", "test_tf", "-100.2"};
String[] doc6 = {"id","7", "group_i", "-1000", "test_i", "8", "test_l", "-50", "test_f", "-100.2"};
assertU(adoc(doc6));
assertU(commit());
ModifiableSolrParams params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_i min=test_tf}");
params.add("fq", "{!collapse field=group_i min=test_f}");
assertQ(req(params), "*[count(//doc)=1]",
"//result/doc[1]/float[@name='id'][.='6.0']");
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field=group_i max=test_tf}");
params.add("fq", "{!collapse field=group_i max=test_f}");
assertQ(req(params), "*[count(//doc)=1]",
"//result/doc[1]/float[@name='id'][.='2.0']");
@ -349,29 +343,29 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
private void testCollapseQueries(String group, String hint, boolean numeric) throws Exception {
String[] doc = {"id","1", "term_s", "YYYY", group, "1", "test_ti", "5", "test_tl", "10", "test_tf", "2000"};
String[] doc = {"id","1", "term_s", "YYYY", group, "1", "test_i", "5", "test_l", "10", "test_f", "2000"};
assertU(adoc(doc));
assertU(commit());
String[] doc1 = {"id","2", "term_s","YYYY", group, "1", "test_ti", "50", "test_tl", "100", "test_tf", "200"};
String[] doc1 = {"id","2", "term_s","YYYY", group, "1", "test_i", "50", "test_l", "100", "test_f", "200"};
assertU(adoc(doc1));
String[] doc2 = {"id","3", "term_s", "YYYY", "test_ti", "5000", "test_tl", "100", "test_tf", "200"};
String[] doc2 = {"id","3", "term_s", "YYYY", "test_i", "5000", "test_l", "100", "test_f", "200"};
assertU(adoc(doc2));
assertU(commit());
String[] doc3 = {"id","4", "term_s", "YYYY", "test_ti", "500", "test_tl", "1000", "test_tf", "2000"};
String[] doc3 = {"id","4", "term_s", "YYYY", "test_i", "500", "test_l", "1000", "test_f", "2000"};
assertU(adoc(doc3));
String[] doc4 = {"id","5", "term_s", "YYYY", group, "2", "test_ti", "4", "test_tl", "10", "test_tf", "2000"};
String[] doc4 = {"id","5", "term_s", "YYYY", group, "2", "test_i", "4", "test_l", "10", "test_f", "2000"};
assertU(adoc(doc4));
assertU(commit());
String[] doc5 = {"id","6", "term_s","YYYY", group, "2", "test_ti", "10", "test_tl", "100", "test_tf", "200"};
String[] doc5 = {"id","6", "term_s","YYYY", group, "2", "test_i", "10", "test_l", "100", "test_f", "200"};
assertU(adoc(doc5));
assertU(commit());
String[] doc6 = {"id","7", "term_s", "YYYY", group, "1", "test_ti", "8", "test_tl", "50", "test_tf", "300"};
String[] doc6 = {"id","7", "term_s", "YYYY", group, "1", "test_i", "8", "test_l", "50", "test_f", "300"};
assertU(adoc(doc6));
assertU(commit());
@ -381,7 +375,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+""+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
assertQ(req(params, "indent", "on"), "*[count(//doc)=2]",
"//result/doc[1]/float[@name='id'][.='2.0']",
"//result/doc[2]/float[@name='id'][.='6.0']"
@ -391,9 +385,9 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// SOLR-5544 test ordering with empty sort param
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" nullPolicy=expand min=test_tf"+hint+"}");
params.add("fq", "{!collapse field="+group+" nullPolicy=expand min=test_f"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
params.add("sort","");
assertQ(req(params), "*[count(//doc)=4]",
"//result/doc[1]/float[@name='id'][.='3.0']",
@ -405,8 +399,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// Test value source collapse criteria
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=field(test_ti)"+hint+"}");
params.add("sort", "test_ti desc");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=field(test_i)"+hint+"}");
params.add("sort", "test_i desc");
assertQ(req(params), "*[count(//doc)=3]",
"//result/doc[1]/float[@name='id'][.='4.0']",
"//result/doc[2]/float[@name='id'][.='1.0']",
@ -418,7 +412,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=cscore()"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
assertQ(req(params), "*[count(//doc)=3]",
"//result/doc[1]/float[@name='id'][.='4.0']",
"//result/doc[2]/float[@name='id'][.='1.0']",
@ -430,7 +424,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=cscore()"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
params.add("fl", "id");
params.add("sort", "id desc");
assertQ(req(params), "*[count(//doc)=3]",
@ -442,9 +436,9 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// Test value source collapse criteria with compound cscore function
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=sum(cscore(),field(test_ti))"+hint+"}");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse min=sum(cscore(),field(test_i))"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
assertQ(req(params), "*[count(//doc)=3]",
"//result/doc[1]/float[@name='id'][.='4.0']",
"//result/doc[2]/float[@name='id'][.='1.0']",
@ -457,7 +451,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params.add("q", "YYYY");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
params.add("qf", "term_s");
params.add("qt", "/elevate");
assertQ(req(params), "*[count(//doc)=4]",
@ -473,7 +467,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params.add("q", "YYYY");
params.add("fq", "{!collapse field="+group + maxscore + " nullPolicy=collapse"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
params.add("qf", "term_s");
params.add("qt", "/elevate");
params.add("elevateIds", "1,5");
@ -485,12 +479,12 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test SOLR-5773 with max field collapse criteria
// try both max & sort localparams as alternate ways to ask for max group head
for (String max : new String[] {" max=test_ti ", " sort='test_ti desc' "}) {
for (String max : new String[] {" max=test_i ", " sort='test_i desc' "}) {
params = new ModifiableSolrParams();
params.add("q", "YYYY");
params.add("fq", "{!collapse field=" + group + max + "nullPolicy=collapse"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
params.add("qf", "term_s");
params.add("qt", "/elevate");
params.add("elevateIds", "1,5");
@ -502,12 +496,12 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test SOLR-5773 with min field collapse criteria
// try both min & sort localparams as alternate ways to ask for min group head
for (String min : new String[] {" min=test_ti ", " sort='test_ti asc' "}) {
for (String min : new String[] {" min=test_i ", " sort='test_i asc' "}) {
params = new ModifiableSolrParams();
params.add("q", "YYYY");
params.add("fq", "{!collapse field=" + group + min + "nullPolicy=collapse"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
params.add("qf", "term_s");
params.add("qt", "/elevate");
params.add("elevateIds", "1,5");
@ -522,7 +516,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params.add("q", "YYYY");
params.add("fq", "{!collapse field="+group+""+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
params.add("qf", "term_s");
params.add("qt", "/elevate");
params.add("elevateIds", "3,4");
@ -536,7 +530,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// Non trivial sort local param for picking group head
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse sort='term_s asc, test_ti asc' "+hint+"}");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse sort='term_s asc, test_i asc' "+hint+"}");
params.add("sort", "id desc");
assertQ(req(params),
"*[count(//doc)=3]",
@ -547,7 +541,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse sort='term_s asc, test_ti desc' "+hint+"}");
params.add("fq", "{!collapse field="+group+" nullPolicy=collapse sort='term_s asc, test_i desc' "+hint+"}");
params.add("sort", "id desc");
assertQ(req(params),
"*[count(//doc)=3]",
@ -560,7 +554,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// Test collapse by min int field and top level sort
// try both min & sort localparams as alternate ways to ask for min group head
for (String min : new String[] {" min=test_ti ", " sort='test_ti asc' "}) {
for (String min : new String[] {" min=test_i ", " sort='test_i asc' "}) {
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group + min + hint+"}");
@ -582,7 +576,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group + min + hint+"}");
params.add("sort", "test_tl asc,id desc");
params.add("sort", "test_l asc,id desc");
assertQ(req(params),
"*[count(//doc)=2]",
"//result/doc[1]/float[@name='id'][.='5.0']",
@ -604,8 +598,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test collapse by max int field
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" max=test_ti"+hint+"}");
params.add("sort", "test_ti asc");
params.add("fq", "{!collapse field="+group+" max=test_i"+hint+"}");
params.add("sort", "test_i asc");
assertQ(req(params), "*[count(//doc)=2]",
"//result/doc[1]/float[@name='id'][.='6.0']",
"//result/doc[2]/float[@name='id'][.='2.0']"
@ -615,8 +609,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test collapse by min long field
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" min=test_tl"+hint+"}");
params.add("sort", "test_ti desc");
params.add("fq", "{!collapse field="+group+" min=test_l"+hint+"}");
params.add("sort", "test_i desc");
assertQ(req(params), "*[count(//doc)=2]",
"//result/doc[1]/float[@name='id'][.='1.0']",
"//result/doc[2]/float[@name='id'][.='5.0']");
@ -625,8 +619,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test collapse by max long field
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" max=test_tl"+hint+"}");
params.add("sort", "test_ti desc");
params.add("fq", "{!collapse field="+group+" max=test_l"+hint+"}");
params.add("sort", "test_i desc");
assertQ(req(params), "*[count(//doc)=2]",
"//result/doc[1]/float[@name='id'][.='2.0']",
"//result/doc[2]/float[@name='id'][.='6.0']");
@ -640,8 +634,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test collapse by min float field
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" min=test_tf"+hint+"}");
params.add("sort", "test_ti desc");
params.add("fq", "{!collapse field="+group+" min=test_f"+hint+"}");
params.add("sort", "test_i desc");
assertQ(req(params), "*[count(//doc)=2]",
"//result/doc[1]/float[@name='id'][.='2.0']",
"//result/doc[2]/float[@name='id'][.='6.0']");
@ -649,8 +643,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test collapse by min float field
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" max=test_tf"+hint+"}");
params.add("sort", "test_ti asc");
params.add("fq", "{!collapse field="+group+" max=test_f"+hint+"}");
params.add("sort", "test_i asc");
assertQ(req(params), "*[count(//doc)=2]",
"//result/doc[1]/float[@name='id'][.='5.0']",
"//result/doc[2]/float[@name='id'][.='1.0']");
@ -658,7 +652,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test collapse by min float field sort by score
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" max=test_tf"+hint+"}");
params.add("fq", "{!collapse field="+group+" max=test_f"+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(id)");
params.add("fl", "score, id");
@ -673,8 +667,8 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// Test collapse using selector field in no docs
// tie selector in all of these cases
for (String selector : new String[] {
" min=bogus_ti ", " sort='bogus_ti asc' ",
" max=bogus_ti ", " sort='bogus_ti desc' ",
" min=bogus_i ", " sort='bogus_i asc' ",
" max=bogus_i ", " sort='bogus_i desc' ",
" min=bogus_tf ", " sort='bogus_tf asc' ",
" max=bogus_tf ", " sort='bogus_tf desc' ",
" sort='bogus_td asc' ", " sort='bogus_td desc' ",
@ -695,16 +689,16 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// attempting to use cscore() in sort local param should fail
assertQEx("expected error trying to sort on a function that includes cscore()",
req(params("q", "{!func}sub(sub(test_tl,1000),id)",
req(params("q", "{!func}sub(sub(test_l,1000),id)",
"fq", "{!collapse field="+group+" sort='abs(cscore()) asc, id asc'}",
"sort", "score asc")),
SolrException.ErrorCode.BAD_REQUEST);
// multiple params for picking groupHead should all fail
for (String bad : new String[] {
"{!collapse field="+group+" min=test_tf max=test_tf}",
"{!collapse field="+group+" min=test_tf sort='test_tf asc'}",
"{!collapse field="+group+" max=test_tf sort='test_tf asc'}" }) {
"{!collapse field="+group+" min=test_f max=test_f}",
"{!collapse field="+group+" min=test_f sort='test_f asc'}",
"{!collapse field="+group+" max=test_f sort='test_f asc'}" }) {
assertQEx("Expected error: " + bad, req(params("q", "*:*", "fq", bad)),
SolrException.ErrorCode.BAD_REQUEST);
}
@ -713,15 +707,15 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// sort used
for (SolrParams collapse : new SolrParams[] {
// these should all be equivilently valid
params("fq", "{!collapse field="+group+" nullPolicy=collapse sort='test_ti asc'"+hint+"}"),
params("fq", "{!collapse field="+group+" nullPolicy=collapse min='' sort='test_ti asc'"+hint+"}"),
params("fq", "{!collapse field="+group+" nullPolicy=collapse max='' sort='test_ti asc'"+hint+"}"),
params("fq", "{!collapse field="+group+" nullPolicy=collapse min=$x sort='test_ti asc'"+hint+"}"),
params("fq", "{!collapse field="+group+" nullPolicy=collapse min=$x sort='test_ti asc'"+hint+"}",
params("fq", "{!collapse field="+group+" nullPolicy=collapse sort='test_i asc'"+hint+"}"),
params("fq", "{!collapse field="+group+" nullPolicy=collapse min='' sort='test_i asc'"+hint+"}"),
params("fq", "{!collapse field="+group+" nullPolicy=collapse max='' sort='test_i asc'"+hint+"}"),
params("fq", "{!collapse field="+group+" nullPolicy=collapse min=$x sort='test_i asc'"+hint+"}"),
params("fq", "{!collapse field="+group+" nullPolicy=collapse min=$x sort='test_i asc'"+hint+"}",
"x",""),
}) {
assertQ(req(collapse, "q", "*:*", "sort", "test_ti desc"),
assertQ(req(collapse, "q", "*:*", "sort", "test_i desc"),
"*[count(//doc)=3]",
"//result/doc[1]/float[@name='id'][.='4.0']",
"//result/doc[2]/float[@name='id'][.='1.0']",
@ -732,7 +726,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test nullPolicy expand
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" max=test_tf nullPolicy=expand"+hint+"}");
params.add("fq", "{!collapse field="+group+" max=test_f nullPolicy=expand"+hint+"}");
params.add("sort", "id desc");
assertQ(req(params), "*[count(//doc)=4]",
"//result/doc[1]/float[@name='id'][.='5.0']",
@ -743,7 +737,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
//Test nullPolicy collapse
params = new ModifiableSolrParams();
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+" max=test_tf nullPolicy=collapse"+hint+"}");
params.add("fq", "{!collapse field="+group+" max=test_f nullPolicy=collapse"+hint+"}");
params.add("sort", "id desc");
assertQ(req(params), "*[count(//doc)=3]",
"//result/doc[1]/float[@name='id'][.='5.0']",
@ -755,12 +749,12 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params.add("q", "*:*");
params.add("fq", "{!collapse field="+group+hint+"}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("fq","{!tag=test_ti}id:5");
params.add("bf", "field(test_i)");
params.add("fq","{!tag=test_i}id:5");
params.add("facet","true");
params.add("facet.field","{!ex=test_ti}test_ti");
params.add("facet.field","{!ex=test_i}test_i");
params.add("facet.mincount", "1");
assertQ(req(params), "*[count(//doc)=1]", "*[count(//lst[@name='facet_fields']/lst[@name='test_ti']/int)=2]");
assertQ(req(params), "*[count(//doc)=1]", "*[count(//lst[@name='facet_fields']/lst[@name='test_i']/int)=2]");
// SOLR-5230 - ensure CollapsingFieldValueCollector.finish() is called
params = new ModifiableSolrParams();
@ -779,7 +773,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
params.add("q", "YYYY");
params.add("fq", "{!collapse field="+group+hint+" nullPolicy=collapse}");
params.add("defType", "edismax");
params.add("bf", "field(test_ti)");
params.add("bf", "field(test_i)");
params.add("qf", "term_s");
params.add("qt", "/elevate");
assertQ(req(params), "*[count(//doc)=3]",
@ -805,7 +799,7 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
String group = (random().nextBoolean() ? "group_s" : "group_s_dv");
// min-or-max is for CollapsingScoreCollector vs. CollapsingFieldValueCollector
String optional_min_or_max = (random().nextBoolean() ? "" : (random().nextBoolean() ? "min=field(test_ti)" : "max=field(test_ti)"));
String optional_min_or_max = (random().nextBoolean() ? "" : (random().nextBoolean() ? "min=field(test_i)" : "max=field(test_i)"));
ModifiableSolrParams params = new ModifiableSolrParams();
params.add("q", "*:*");
@ -817,17 +811,17 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
// as unlikely as this test seems, it's important for the possibility that a segment exists w/o
// any live docs that have DocValues for the group field -- ie: every doc in segment is in null group.
assertU(adoc("id", "1", "group_s", "group1", "test_ti", "5", "test_tl", "10"));
assertU(adoc("id", "1", "group_s", "group1", "test_i", "5", "test_l", "10"));
assertU(commit());
assertU(adoc("id", "2", "group_s", "group1", "test_ti", "5", "test_tl", "1000"));
assertU(adoc("id", "3", "group_s", "group1", "test_ti", "5", "test_tl", "1000"));
assertU(adoc("id", "4", "group_s", "group1", "test_ti", "10", "test_tl", "100"));
assertU(adoc("id", "2", "group_s", "group1", "test_i", "5", "test_l", "1000"));
assertU(adoc("id", "3", "group_s", "group1", "test_i", "5", "test_l", "1000"));
assertU(adoc("id", "4", "group_s", "group1", "test_i", "10", "test_l", "100"));
//
assertU(adoc("id", "5", "group_s", "group2", "test_ti", "5", "test_tl", "10", "term_s", "YYYY"));
assertU(adoc("id", "5", "group_s", "group2", "test_i", "5", "test_l", "10", "term_s", "YYYY"));
assertU(commit());
assertU(adoc("id", "6", "group_s", "group2", "test_ti", "5", "test_tl","1000"));
assertU(adoc("id", "7", "group_s", "group2", "test_ti", "5", "test_tl","1000", "term_s", "XXXX"));
assertU(adoc("id", "8", "group_s", "group2", "test_ti", "10","test_tl", "100"));
assertU(adoc("id", "6", "group_s", "group2", "test_i", "5", "test_l","1000"));
assertU(adoc("id", "7", "group_s", "group2", "test_i", "5", "test_l","1000", "term_s", "XXXX"));
assertU(adoc("id", "8", "group_s", "group2", "test_i", "10","test_l", "100"));
assertU(commit());
// none of these grouping fields are in any doc
@ -835,17 +829,17 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
"field=bogus_s", "field=bogus_s_dv",
"field=bogus_s hint=top_fc", // alternative docvalues codepath w/ hint
"field=bogus_s_dv hint=top_fc", // alternative docvalues codepath w/ hint
"field=bogus_ti", "field=bogus_tf" }) {
"field=bogus_i", "field=bogus_tf" }) {
// for any of these selectors, behavior of these checks should be consistent
for (String selector : new String[] {
"", " sort='score desc' ",
" min=test_ti ", " max=test_ti ", " sort='test_ti asc' ", " sort='test_ti desc' ",
" min=test_tf ", " max=test_tf ", " sort='test_tf asc' ", " sort='test_tf desc' ",
" min=test_i ", " max=test_i ", " sort='test_i asc' ", " sort='test_i desc' ",
" min=test_f ", " max=test_f ", " sort='test_f asc' ", " sort='test_f desc' ",
" sort='group_s asc' ", " sort='group_s desc' ",
// fields that don't exist
" min=bogus_sort_ti ", " max=bogus_sort_ti ",
" sort='bogus_sort_ti asc' ", " sort='bogus_sort_ti desc' ",
" min=bogus_sort_i ", " max=bogus_sort_i ",
" sort='bogus_sort_i asc' ", " sort='bogus_sort_i desc' ",
" sort='bogus_sort_s asc' ", " sort='bogus_sort_s desc' ",
}) {

View File

@ -20,11 +20,9 @@ import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
import org.apache.lucene.util.TestUtil;
import org.apache.solr.CursorPagingTest;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
@ -37,9 +35,6 @@ import static org.apache.solr.search.CollapsingQParserPlugin.NULL_EXPAND;
import org.junit.AfterClass;
import org.junit.BeforeClass;
//We want codecs that support DocValues, and ones supporting blank/empty values.
@SuppressCodecs({"Appending","Lucene3x","Lucene40","Lucene41","Lucene42"})
@SuppressPointFields
public class TestRandomCollapseQParserPlugin extends SolrTestCaseJ4 {
/** Full SolrServer instance for arbitrary introspection of response data and adding fqs */