mirror of https://github.com/apache/lucene.git
SOLR-14333: Implement toString in Collapse filter (#1371)
This commit is contained in:
parent
2b692ccb71
commit
1dba76c0d3
|
@ -281,6 +281,10 @@ Other Changes
|
||||||
|
|
||||||
* SOLR-14876: Upgrade to zookeeper 3.6.2 (odidev via Erick Erickson)
|
* SOLR-14876: Upgrade to zookeeper 3.6.2 (odidev via Erick Erickson)
|
||||||
|
|
||||||
|
* SOLR-14333: Implement toString in Collapse filter so that proper parsed queries returned in debug response.
|
||||||
|
Also, Deprecate unused constants NULL_COLLAPSE, NULL_IGNORE, NULL_EXPAND, HINT_MULTI_DOCVALUES in collapse parser.
|
||||||
|
(Guna Sekhar Dora Kovvuru, Munendra S N, Mike Drob)
|
||||||
|
|
||||||
================== 8.6.2 ==================
|
================== 8.6.2 ==================
|
||||||
|
|
||||||
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
|
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
|
||||||
|
|
|
@ -122,12 +122,57 @@ import static org.apache.solr.common.params.CommonParams.SORT;
|
||||||
public class CollapsingQParserPlugin extends QParserPlugin {
|
public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
|
|
||||||
public static final String NAME = "collapse";
|
public static final String NAME = "collapse";
|
||||||
public static final String NULL_COLLAPSE = "collapse";
|
|
||||||
public static final String NULL_IGNORE = "ignore";
|
|
||||||
public static final String NULL_EXPAND = "expand";
|
|
||||||
public static final String HINT_TOP_FC = "top_fc";
|
public static final String HINT_TOP_FC = "top_fc";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link NullPolicy} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static final String NULL_COLLAPSE = "collapse";
|
||||||
|
@Deprecated
|
||||||
|
public static final String NULL_IGNORE = "ignore";
|
||||||
|
@Deprecated
|
||||||
|
public static final String NULL_EXPAND = "expand";
|
||||||
|
@Deprecated
|
||||||
public static final String HINT_MULTI_DOCVALUES = "multi_docvalues";
|
public static final String HINT_MULTI_DOCVALUES = "multi_docvalues";
|
||||||
|
|
||||||
|
public enum NullPolicy {
|
||||||
|
IGNORE("ignore", 0),
|
||||||
|
COLLAPSE("collapse", 1),
|
||||||
|
EXPAND("expand", 2);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final int code;
|
||||||
|
|
||||||
|
NullPolicy(String name, int code) {
|
||||||
|
this.name = name;
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NullPolicy fromString(String nullPolicy) {
|
||||||
|
if (StringUtils.isEmpty(nullPolicy)) {
|
||||||
|
return DEFAULT_POLICY;
|
||||||
|
}
|
||||||
|
switch (nullPolicy) {
|
||||||
|
case "ignore": return IGNORE;
|
||||||
|
case "collapse": return COLLAPSE;
|
||||||
|
case "expand": return EXPAND;
|
||||||
|
default:
|
||||||
|
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Invalid nullPolicy: " + nullPolicy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NullPolicy DEFAULT_POLICY = IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest request) {
|
public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest request) {
|
||||||
return new CollapsingQParser(qstr, localParams, params, request);
|
return new CollapsingQParser(qstr, localParams, params, request);
|
||||||
|
@ -188,6 +233,11 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
return 17 * (31 + selectorText.hashCode()) * (31 + type.hashCode());
|
return 17 * (31 + selectorText.hashCode()) * (31 + type.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return "GroupHeadSelector(selectorText=" + this.selectorText + ", type=" +this.type + ")";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns a new GroupHeadSelector based on the specified local params
|
* returns a new GroupHeadSelector based on the specified local params
|
||||||
*/
|
*/
|
||||||
|
@ -221,11 +271,8 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
public String hint;
|
public String hint;
|
||||||
private boolean needsScores = true;
|
private boolean needsScores = true;
|
||||||
private boolean needsScores4Collapsing = false;
|
private boolean needsScores4Collapsing = false;
|
||||||
private int nullPolicy;
|
private NullPolicy nullPolicy;
|
||||||
private Set<BytesRef> boosted; // ordered by "priority"
|
private Set<BytesRef> boosted; // ordered by "priority"
|
||||||
public static final int NULL_POLICY_IGNORE = 0;
|
|
||||||
public static final int NULL_POLICY_COLLAPSE = 1;
|
|
||||||
public static final int NULL_POLICY_EXPAND = 2;
|
|
||||||
private int size;
|
private int size;
|
||||||
|
|
||||||
public String getField(){
|
public String getField(){
|
||||||
|
@ -254,7 +301,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
int hashCode = classHash();
|
int hashCode = classHash();
|
||||||
hashCode = 31 * hashCode + collapseField.hashCode();
|
hashCode = 31 * hashCode + collapseField.hashCode();
|
||||||
hashCode = 31 * hashCode + groupHeadSelector.hashCode();
|
hashCode = 31 * hashCode + groupHeadSelector.hashCode();
|
||||||
hashCode = 31 * hashCode + nullPolicy;
|
hashCode = 31 * hashCode + nullPolicy.hashCode();
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +326,12 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString(String s) {
|
public String toString(String s) {
|
||||||
return s;
|
return "CollapsingPostFilter(field=" + this.collapseField +
|
||||||
|
", nullPolicy=" + this.nullPolicy.getName() + ", " +
|
||||||
|
this.groupHeadSelector +
|
||||||
|
(hint == null ? "": ", hint=" + this.hint) +
|
||||||
|
", size=" + this.size
|
||||||
|
+ ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public CollapsingPostFilter(SolrParams localParams, SolrParams params, SolrQueryRequest request) {
|
public CollapsingPostFilter(SolrParams localParams, SolrParams params, SolrQueryRequest request) {
|
||||||
|
@ -354,16 +406,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String nPolicy = localParams.get("nullPolicy", NULL_IGNORE);
|
this.nullPolicy = NullPolicy.fromString(localParams.get("nullPolicy"));
|
||||||
if(nPolicy.equals(NULL_IGNORE)) {
|
|
||||||
this.nullPolicy = NULL_POLICY_IGNORE;
|
|
||||||
} else if (nPolicy.equals(NULL_COLLAPSE)) {
|
|
||||||
this.nullPolicy = NULL_POLICY_COLLAPSE;
|
|
||||||
} else if(nPolicy.equals((NULL_EXPAND))) {
|
|
||||||
this.nullPolicy = NULL_POLICY_EXPAND;
|
|
||||||
} else {
|
|
||||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Invalid nullPolicy:"+nPolicy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
|
@ -392,7 +435,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
return collectorFactory.getCollector(this.collapseField,
|
return collectorFactory.getCollector(this.collapseField,
|
||||||
this.groupHeadSelector,
|
this.groupHeadSelector,
|
||||||
this.sortSpec,
|
this.sortSpec,
|
||||||
this.nullPolicy,
|
this.nullPolicy.getCode(),
|
||||||
this.hint,
|
this.hint,
|
||||||
this.needsScores4Collapsing,
|
this.needsScores4Collapsing,
|
||||||
this.needsScores,
|
this.needsScores,
|
||||||
|
@ -552,7 +595,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
this.ords = new IntIntDynamicMap(valueCount, -1);
|
this.ords = new IntIntDynamicMap(valueCount, -1);
|
||||||
this.scores = new IntFloatDynamicMap(valueCount, -Float.MAX_VALUE);
|
this.scores = new IntFloatDynamicMap(valueCount, -Float.MAX_VALUE);
|
||||||
this.nullPolicy = nullPolicy;
|
this.nullPolicy = nullPolicy;
|
||||||
if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
nullScores = new FloatArrayList();
|
nullScores = new FloatArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,13 +663,13 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
ords.put(ord, globalDoc);
|
ords.put(ord, globalDoc);
|
||||||
scores.put(ord, score);
|
scores.put(ord, score);
|
||||||
}
|
}
|
||||||
} else if(nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
float score = scorer.score();
|
float score = scorer.score();
|
||||||
if(score > nullScore) {
|
if(score > nullScore) {
|
||||||
nullScore = score;
|
nullScore = score;
|
||||||
nullDoc = globalDoc;
|
nullDoc = globalDoc;
|
||||||
}
|
}
|
||||||
} else if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
collapsedSet.set(globalDoc);
|
collapsedSet.set(globalDoc);
|
||||||
nullScores.add(scorer.score());
|
nullScores.add(scorer.score());
|
||||||
}
|
}
|
||||||
|
@ -716,9 +759,9 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
dummy.score = scores.get(ord);
|
dummy.score = scores.get(ord);
|
||||||
} else if(boosts && mergeBoost.boost(docId)) {
|
} else if(boosts && mergeBoost.boost(docId)) {
|
||||||
//Ignore so it doesn't mess up the null scoring.
|
//Ignore so it doesn't mess up the null scoring.
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
dummy.score = nullScore;
|
dummy.score = nullScore;
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
dummy.score = nullScores.get(++index);
|
dummy.score = nullScores.get(++index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,7 +815,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
this.collapsedSet = new FixedBitSet(maxDoc);
|
this.collapsedSet = new FixedBitSet(maxDoc);
|
||||||
this.nullValue = nullValue;
|
this.nullValue = nullValue;
|
||||||
this.nullPolicy = nullPolicy;
|
this.nullPolicy = nullPolicy;
|
||||||
if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
nullScores = new FloatArrayList();
|
nullScores = new FloatArrayList();
|
||||||
}
|
}
|
||||||
this.cmap = new IntLongHashMap(size);
|
this.cmap = new IntLongHashMap(size);
|
||||||
|
@ -839,13 +882,13 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
long scoreDoc = (((long)Float.floatToRawIntBits(score))<<32)+globalDoc;
|
long scoreDoc = (((long)Float.floatToRawIntBits(score))<<32)+globalDoc;
|
||||||
cmap.indexInsert(idx, collapseValue, scoreDoc);
|
cmap.indexInsert(idx, collapseValue, scoreDoc);
|
||||||
}
|
}
|
||||||
} else if(nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
float score = scorer.score();
|
float score = scorer.score();
|
||||||
if(score > this.nullScore) {
|
if(score > this.nullScore) {
|
||||||
this.nullScore = score;
|
this.nullScore = score;
|
||||||
this.nullDoc = globalDoc;
|
this.nullDoc = globalDoc;
|
||||||
}
|
}
|
||||||
} else if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
collapsedSet.set(globalDoc);
|
collapsedSet.set(globalDoc);
|
||||||
nullScores.add(scorer.score());
|
nullScores.add(scorer.score());
|
||||||
}
|
}
|
||||||
|
@ -917,9 +960,9 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
dummy.score = Float.intBitsToFloat((int)(scoreDoc>>32));
|
dummy.score = Float.intBitsToFloat((int)(scoreDoc>>32));
|
||||||
} else if(boosts && mergeBoost.boost(globalDoc)) {
|
} else if(boosts && mergeBoost.boost(globalDoc)) {
|
||||||
//Ignore so boosted documents don't mess up the null scoring policies.
|
//Ignore so boosted documents don't mess up the null scoring policies.
|
||||||
} else if (nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if (nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
dummy.score = nullScore;
|
dummy.score = nullScore;
|
||||||
} else if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
dummy.score = nullScores.get(nullScoreIndex++);
|
dummy.score = nullScores.get(nullScoreIndex++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1114,9 +1157,9 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
} else if (mergeBoost != null && mergeBoost.boost(globalDoc)) {
|
} else if (mergeBoost != null && mergeBoost.boost(globalDoc)) {
|
||||||
//It's an elevated doc so no score is needed
|
//It's an elevated doc so no score is needed
|
||||||
dummy.score = 0F;
|
dummy.score = 0F;
|
||||||
} else if (nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if (nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
dummy.score = nullScore;
|
dummy.score = nullScore;
|
||||||
} else if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
dummy.score = nullScores.get(nullScoreIndex++);
|
dummy.score = nullScores.get(nullScoreIndex++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1273,9 +1316,9 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
} else if (mergeBoost != null && mergeBoost.boost(globalDoc)) {
|
} else if (mergeBoost != null && mergeBoost.boost(globalDoc)) {
|
||||||
//Its an elevated doc so no score is needed
|
//Its an elevated doc so no score is needed
|
||||||
dummy.score = 0F;
|
dummy.score = 0F;
|
||||||
} else if (nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if (nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
dummy.score = nullScore;
|
dummy.score = nullScore;
|
||||||
} else if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
dummy.score = nullScores.get(nullScoreIndex++);
|
dummy.score = nullScores.get(nullScoreIndex++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1538,7 +1581,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
|
|
||||||
if (this.needsScores) {
|
if (this.needsScores) {
|
||||||
this.scores = new IntFloatDynamicMap(valueCount, 0.0f);
|
this.scores = new IntFloatDynamicMap(valueCount, 0.0f);
|
||||||
if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
nullScores = new FloatArrayList();
|
nullScores = new FloatArrayList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1648,7 +1691,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
scores.put(ord, scorer.score());
|
scores.put(ord, scorer.score());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if(comp.test(currentVal, nullVal)) {
|
if(comp.test(currentVal, nullVal)) {
|
||||||
nullVal = currentVal;
|
nullVal = currentVal;
|
||||||
nullDoc = globalDoc;
|
nullDoc = globalDoc;
|
||||||
|
@ -1656,7 +1699,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
nullScore = scorer.score();
|
nullScore = scorer.score();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if(needsScores) {
|
if(needsScores) {
|
||||||
nullScores.add(scorer.score());
|
nullScores.add(scorer.score());
|
||||||
|
@ -1729,7 +1772,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
scores.put(ord, scorer.score());
|
scores.put(ord, scorer.score());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if(comp.test(currentVal, nullVal)) {
|
if(comp.test(currentVal, nullVal)) {
|
||||||
nullVal = currentVal;
|
nullVal = currentVal;
|
||||||
nullDoc = globalDoc;
|
nullDoc = globalDoc;
|
||||||
|
@ -1737,7 +1780,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
nullScore = scorer.score();
|
nullScore = scorer.score();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if(needsScores) {
|
if(needsScores) {
|
||||||
nullScores.add(scorer.score());
|
nullScores.add(scorer.score());
|
||||||
|
@ -1807,7 +1850,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
scores.put(ord, scorer.score());
|
scores.put(ord, scorer.score());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if(comp.test(currentVal, nullVal)) {
|
if(comp.test(currentVal, nullVal)) {
|
||||||
nullVal = currentVal;
|
nullVal = currentVal;
|
||||||
nullDoc = globalDoc;
|
nullDoc = globalDoc;
|
||||||
|
@ -1815,7 +1858,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
nullScore = scorer.score();
|
nullScore = scorer.score();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if(needsScores) {
|
if(needsScores) {
|
||||||
nullScores.add(scorer.score());
|
nullScores.add(scorer.score());
|
||||||
|
@ -1900,7 +1943,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
scores.put(ord, score);
|
scores.put(ord, score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if(comp.test(currentVal, nullVal)) {
|
if(comp.test(currentVal, nullVal)) {
|
||||||
nullVal = currentVal;
|
nullVal = currentVal;
|
||||||
nullDoc = globalDoc;
|
nullDoc = globalDoc;
|
||||||
|
@ -1911,7 +1954,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
nullScore = score;
|
nullScore = score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if(needsScores) {
|
if(needsScores) {
|
||||||
if (!needsScores4Collapsing) {
|
if (!needsScores4Collapsing) {
|
||||||
|
@ -2001,7 +2044,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if (this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if (-1 == nullDoc) {
|
if (-1 == nullDoc) {
|
||||||
// we've never seen a doc with null collapse key yet, treat it as the null group head for now
|
// we've never seen a doc with null collapse key yet, treat it as the null group head for now
|
||||||
compareState.setNullGroupValues(contextDoc);
|
compareState.setNullGroupValues(contextDoc);
|
||||||
|
@ -2024,7 +2067,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if (needsScores) {
|
if (needsScores) {
|
||||||
if (!needsScores4Collapsing) {
|
if (!needsScores4Collapsing) {
|
||||||
|
@ -2094,7 +2137,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
|
|
||||||
if(needsScores) {
|
if(needsScores) {
|
||||||
this.scores = new IntFloatDynamicMap(size, 0.0f);
|
this.scores = new IntFloatDynamicMap(size, 0.0f);
|
||||||
if(nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
if(nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
nullScores = new FloatArrayList();
|
nullScores = new FloatArrayList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2236,7 +2279,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
scores.put(index, scorer.score());
|
scores.put(index, scorer.score());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if(comp.test(currentVal, nullCompVal)) {
|
if(comp.test(currentVal, nullCompVal)) {
|
||||||
nullCompVal = currentVal;
|
nullCompVal = currentVal;
|
||||||
nullDoc = globalDoc;
|
nullDoc = globalDoc;
|
||||||
|
@ -2244,7 +2287,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
nullScore = scorer.score();
|
nullScore = scorer.score();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if(needsScores) {
|
if(needsScores) {
|
||||||
nullScores.add(scorer.score());
|
nullScores.add(scorer.score());
|
||||||
|
@ -2329,7 +2372,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
scores.put(index, scorer.score());
|
scores.put(index, scorer.score());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if(comp.test(currentVal, nullCompVal)) {
|
if(comp.test(currentVal, nullCompVal)) {
|
||||||
nullCompVal = currentVal;
|
nullCompVal = currentVal;
|
||||||
nullDoc = globalDoc;
|
nullDoc = globalDoc;
|
||||||
|
@ -2337,7 +2380,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
nullScore = scorer.score();
|
nullScore = scorer.score();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if(needsScores) {
|
if(needsScores) {
|
||||||
nullScores.add(scorer.score());
|
nullScores.add(scorer.score());
|
||||||
|
@ -2445,7 +2488,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
scores.put(index, score);
|
scores.put(index, score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if(comp.test(currentVal, nullCompVal)) {
|
if(comp.test(currentVal, nullCompVal)) {
|
||||||
nullCompVal = currentVal;
|
nullCompVal = currentVal;
|
||||||
nullDoc = globalDoc;
|
nullDoc = globalDoc;
|
||||||
|
@ -2456,7 +2499,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
nullScore = score;
|
nullScore = score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if(needsScores) {
|
if(needsScores) {
|
||||||
if (!needsScores4Collapsing) {
|
if (!needsScores4Collapsing) {
|
||||||
|
@ -2556,7 +2599,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
scores.put(index, score);
|
scores.put(index, score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_COLLAPSE) {
|
} else if(this.nullPolicy == NullPolicy.COLLAPSE.getCode()) {
|
||||||
if (-1 == nullDoc) {
|
if (-1 == nullDoc) {
|
||||||
// we've never seen a doc with null collapse key yet, treat it as the null group head for now
|
// we've never seen a doc with null collapse key yet, treat it as the null group head for now
|
||||||
compareState.setNullGroupValues(contextDoc);
|
compareState.setNullGroupValues(contextDoc);
|
||||||
|
@ -2579,7 +2622,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(this.nullPolicy == CollapsingPostFilter.NULL_POLICY_EXPAND) {
|
} else if(this.nullPolicy == NullPolicy.EXPAND.getCode()) {
|
||||||
this.collapsedSet.set(globalDoc);
|
this.collapsedSet.set(globalDoc);
|
||||||
if (needsScores) {
|
if (needsScores) {
|
||||||
if (!needsScores4Collapsing) {
|
if (!needsScores4Collapsing) {
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.solr.search;
|
package org.apache.solr.search;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.lucene.util.TestUtil;
|
import org.apache.lucene.util.TestUtil;
|
||||||
import org.apache.solr.CursorPagingTest;
|
import org.apache.solr.CursorPagingTest;
|
||||||
|
@ -27,14 +28,14 @@ import org.apache.solr.client.solrj.SolrClient;
|
||||||
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
|
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
import org.apache.solr.common.SolrDocument;
|
import org.apache.solr.common.SolrDocument;
|
||||||
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.common.SolrInputDocument;
|
import org.apache.solr.common.SolrInputDocument;
|
||||||
import org.apache.solr.common.params.SolrParams;
|
import org.apache.solr.common.params.SolrParams;
|
||||||
import static org.apache.solr.search.CollapsingQParserPlugin.NULL_IGNORE;
|
|
||||||
import static org.apache.solr.search.CollapsingQParserPlugin.NULL_COLLAPSE;
|
|
||||||
import static org.apache.solr.search.CollapsingQParserPlugin.NULL_EXPAND;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.StringContains.containsString;
|
||||||
|
|
||||||
public class TestRandomCollapseQParserPlugin extends SolrTestCaseJ4 {
|
public class TestRandomCollapseQParserPlugin extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
/** Full SolrServer instance for arbitrary introspection of response data and adding fqs */
|
/** Full SolrServer instance for arbitrary introspection of response data and adding fqs */
|
||||||
|
@ -43,7 +44,9 @@ public class TestRandomCollapseQParserPlugin extends SolrTestCaseJ4 {
|
||||||
public static List<String> ALL_COLLAPSE_FIELD_NAMES;
|
public static List<String> ALL_COLLAPSE_FIELD_NAMES;
|
||||||
|
|
||||||
private static String[] NULL_POLICIES
|
private static String[] NULL_POLICIES
|
||||||
= new String[] {NULL_IGNORE, NULL_COLLAPSE, NULL_EXPAND};
|
= new String[] {CollapsingQParserPlugin.NullPolicy.IGNORE.getName(),
|
||||||
|
CollapsingQParserPlugin.NullPolicy.COLLAPSE.getName(),
|
||||||
|
CollapsingQParserPlugin.NullPolicy.EXPAND.getName()};
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void buildIndexAndClient() throws Exception {
|
public static void buildIndexAndClient() throws Exception {
|
||||||
|
@ -143,7 +146,7 @@ public class TestRandomCollapseQParserPlugin extends SolrTestCaseJ4 {
|
||||||
"" : " size=" + TestUtil.nextInt(random(),1,10000);
|
"" : " size=" + TestUtil.nextInt(random(),1,10000);
|
||||||
|
|
||||||
final String nullPolicy = randomNullPolicy();
|
final String nullPolicy = randomNullPolicy();
|
||||||
final String nullPs = NULL_IGNORE.equals(nullPolicy)
|
final String nullPs = nullPolicy.equals(CollapsingQParserPlugin.NullPolicy.IGNORE.getName())
|
||||||
// ignore is default, randomly be explicit about it
|
// ignore is default, randomly be explicit about it
|
||||||
? (random().nextBoolean() ? "" : " nullPolicy=ignore")
|
? (random().nextBoolean() ? "" : " nullPolicy=ignore")
|
||||||
: (" nullPolicy=" + nullPolicy);
|
: (" nullPolicy=" + nullPolicy);
|
||||||
|
@ -162,14 +165,14 @@ public class TestRandomCollapseQParserPlugin extends SolrTestCaseJ4 {
|
||||||
final Object collapseVal = doc.getFieldValue(collapseField);
|
final Object collapseVal = doc.getFieldValue(collapseField);
|
||||||
|
|
||||||
if (null == collapseVal) {
|
if (null == collapseVal) {
|
||||||
if (NULL_EXPAND.equals(nullPolicy)) {
|
if (nullPolicy.equals(CollapsingQParserPlugin.NullPolicy.EXPAND.getName())) {
|
||||||
// nothing to check for this doc, it's in its own group
|
// nothing to check for this doc, it's in its own group
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertFalse(groupHeadId + " has null collapseVal but nullPolicy==ignore; " +
|
assertFalse(groupHeadId + " has null collapseVal but nullPolicy==ignore; " +
|
||||||
"mainP: " + mainP + ", collapseP: " + collapseP,
|
"mainP: " + mainP + ", collapseP: " + collapseP,
|
||||||
NULL_IGNORE.equals(nullPolicy));
|
nullPolicy.equals(CollapsingQParserPlugin.NullPolicy.IGNORE.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// workaround for SOLR-8082...
|
// workaround for SOLR-8082...
|
||||||
|
@ -204,6 +207,40 @@ public class TestRandomCollapseQParserPlugin extends SolrTestCaseJ4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testParsedFilterQueryResponse() throws Exception {
|
||||||
|
String nullPolicy = randomNullPolicy();
|
||||||
|
String groupHeadSort = "'_version_ asc'";
|
||||||
|
String collapseSize = "5000";
|
||||||
|
String collapseHint = "top_fc";
|
||||||
|
String filterQuery = "{!collapse field=id sort=" + groupHeadSort + " nullPolicy=" + nullPolicy + " size=" +
|
||||||
|
collapseSize + " hint=" + collapseHint + "}";
|
||||||
|
SolrParams solrParams = params("q", "*:*", "rows", "0", "debug", "true", "fq", filterQuery);
|
||||||
|
|
||||||
|
QueryResponse response = SOLR.query(solrParams);
|
||||||
|
// Query name is occurring twice, this should be handled in QueryParsing.toString
|
||||||
|
String expectedParsedFilterString = "CollapsingPostFilter(CollapsingPostFilter(field=id, " +
|
||||||
|
"nullPolicy=" + nullPolicy + ", GroupHeadSelector(selectorText=" + groupHeadSort.substring(1,
|
||||||
|
groupHeadSort.length() - 1) + ", type=SORT" +
|
||||||
|
"), hint=" + collapseHint + ", size=" + collapseSize + "))";
|
||||||
|
List<String> expectedParsedFilterQuery = Collections.singletonList(expectedParsedFilterString);
|
||||||
|
assertEquals(expectedParsedFilterQuery, response.getDebugMap().get("parsed_filter_queries"));
|
||||||
|
assertEquals(Collections.singletonList(filterQuery), response.getDebugMap().get("filter_queries"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNullPolicy() {
|
||||||
|
String nullPolicy = "xyz";
|
||||||
|
String groupHeadSort = "'_version_ asc'";
|
||||||
|
String filterQuery = "{!collapse field=id sort=" + groupHeadSort + " nullPolicy=" + nullPolicy + "}";
|
||||||
|
SolrParams solrParams = params("q", "*:*", "fq", filterQuery);
|
||||||
|
|
||||||
|
SolrException e = expectThrows(SolrException.class, () -> SOLR.query(solrParams));
|
||||||
|
assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, e.code());
|
||||||
|
assertThat(e.getMessage(), containsString("Invalid nullPolicy: " + nullPolicy));
|
||||||
|
|
||||||
|
// valid nullPolicy
|
||||||
|
assertQ(req("q", "*:*", "fq", "{!collapse field=id nullPolicy=" + randomNullPolicy() + "}"));
|
||||||
|
}
|
||||||
|
|
||||||
private String randomNullPolicy() {
|
private String randomNullPolicy() {
|
||||||
return NULL_POLICIES[ TestUtil.nextInt(random(), 0, NULL_POLICIES.length-1) ];
|
return NULL_POLICIES[ TestUtil.nextInt(random(), 0, NULL_POLICIES.length-1) ];
|
||||||
|
|
Loading…
Reference in New Issue