mirror of https://github.com/apache/lucene.git
SOLR-5773: CollapsingQParserPlugin should make elevated documents the group head
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1583500 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
719d5cd12e
commit
002f3d1b6b
|
@ -253,6 +253,9 @@ Other Changes
|
||||||
* SOLR-5934: LBHttpSolrServer exception handling improvement and small test
|
* SOLR-5934: LBHttpSolrServer exception handling improvement and small test
|
||||||
improvements. (Gregory Chanan via Mark Miller)
|
improvements. (Gregory Chanan via Mark Miller)
|
||||||
|
|
||||||
|
* SOLR-5773: CollapsingQParserPlugin should make elevated documents the
|
||||||
|
group head. (David Boychuck, Joel Bernstein)
|
||||||
|
|
||||||
================== 4.7.1 ==================
|
================== 4.7.1 ==================
|
||||||
|
|
||||||
Versions of Major Components
|
Versions of Major Components
|
||||||
|
|
|
@ -443,6 +443,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
private int nullDoc;
|
private int nullDoc;
|
||||||
private FloatArrayList nullScores;
|
private FloatArrayList nullScores;
|
||||||
private IntOpenHashSet boostDocs;
|
private IntOpenHashSet boostDocs;
|
||||||
|
private int[] boostOrds;
|
||||||
|
|
||||||
public CollapsingScoreCollector(int maxDoc,
|
public CollapsingScoreCollector(int maxDoc,
|
||||||
int segments,
|
int segments,
|
||||||
|
@ -455,11 +456,19 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
this.boostDocs = boostDocs;
|
this.boostDocs = boostDocs;
|
||||||
if(this.boostDocs != null) {
|
if(this.boostDocs != null) {
|
||||||
//Set the elevated docs now.
|
//Set the elevated docs now.
|
||||||
|
IntOpenHashSet boostG = new IntOpenHashSet();
|
||||||
Iterator<IntCursor> it = this.boostDocs.iterator();
|
Iterator<IntCursor> it = this.boostDocs.iterator();
|
||||||
while(it.hasNext()) {
|
while(it.hasNext()) {
|
||||||
IntCursor cursor = it.next();
|
IntCursor cursor = it.next();
|
||||||
this.collapsedSet.set(cursor.value);
|
int i = cursor.value;
|
||||||
|
this.collapsedSet.set(i);
|
||||||
|
int ord = values.getOrd(i);
|
||||||
|
if(ord > -1) {
|
||||||
|
boostG.add(ord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
boostOrds = boostG.toArray();
|
||||||
|
Arrays.sort(boostOrds);
|
||||||
}
|
}
|
||||||
this.values = values;
|
this.values = values;
|
||||||
int valueCount = values.getValueCount();
|
int valueCount = values.getValueCount();
|
||||||
|
@ -489,6 +498,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
public void collect(int docId) throws IOException {
|
public void collect(int docId) throws IOException {
|
||||||
int globalDoc = docId+this.docBase;
|
int globalDoc = docId+this.docBase;
|
||||||
int ord = values.getOrd(globalDoc);
|
int ord = values.getOrd(globalDoc);
|
||||||
|
|
||||||
if(ord > -1) {
|
if(ord > -1) {
|
||||||
float score = scorer.score();
|
float score = scorer.score();
|
||||||
if(score > scores[ord]) {
|
if(score > scores[ord]) {
|
||||||
|
@ -520,6 +530,12 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
this.collapsedSet.set(nullDoc);
|
this.collapsedSet.set(nullDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.boostOrds != null) {
|
||||||
|
for(int i=0; i<this.boostOrds.length; i++) {
|
||||||
|
ords[boostOrds[i]] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(int i=0; i<ords.length; i++) {
|
for(int i=0; i<ords.length; i++) {
|
||||||
int doc = ords[i];
|
int doc = ords[i];
|
||||||
if(doc > -1) {
|
if(doc > -1) {
|
||||||
|
@ -539,6 +555,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
while((docId = it.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
|
while((docId = it.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
|
||||||
|
|
||||||
int ord = values.getOrd(docId);
|
int ord = values.getOrd(docId);
|
||||||
|
|
||||||
if(ord > -1) {
|
if(ord > -1) {
|
||||||
dummy.score = scores[ord];
|
dummy.score = scores[ord];
|
||||||
} else if(this.boostDocs != null && boostDocs.contains(docId)) {
|
} else if(this.boostDocs != null && boostDocs.contains(docId)) {
|
||||||
|
@ -600,14 +617,14 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
this.needsScores = needsScores;
|
this.needsScores = needsScores;
|
||||||
this.boostDocs = boostDocs;
|
this.boostDocs = boostDocs;
|
||||||
if(funcQuery != null) {
|
if(funcQuery != null) {
|
||||||
this.fieldValueCollapse = new ValueSourceCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs, funcQuery, searcher);
|
this.fieldValueCollapse = new ValueSourceCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs, funcQuery, searcher, values);
|
||||||
} else {
|
} else {
|
||||||
if(fieldType instanceof TrieIntField) {
|
if(fieldType instanceof TrieIntField) {
|
||||||
this.fieldValueCollapse = new IntValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
|
this.fieldValueCollapse = new IntValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs, values);
|
||||||
} else if(fieldType instanceof TrieLongField) {
|
} else if(fieldType instanceof TrieLongField) {
|
||||||
this.fieldValueCollapse = new LongValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
|
this.fieldValueCollapse = new LongValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs, values);
|
||||||
} else if(fieldType instanceof TrieFloatField) {
|
} else if(fieldType instanceof TrieFloatField) {
|
||||||
this.fieldValueCollapse = new FloatValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs);
|
this.fieldValueCollapse = new FloatValueCollapse(maxDoc, field, nullPolicy, new int[valueCount], max, this.needsScores, boostDocs, values);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("min/max must be either TrieInt, TrieLong or TrieFloat.");
|
throw new IOException("min/max must be either TrieInt, TrieLong or TrieFloat.");
|
||||||
}
|
}
|
||||||
|
@ -696,6 +713,7 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
protected float[] scores;
|
protected float[] scores;
|
||||||
protected FixedBitSet collapsedSet;
|
protected FixedBitSet collapsedSet;
|
||||||
protected IntOpenHashSet boostDocs;
|
protected IntOpenHashSet boostDocs;
|
||||||
|
protected int[] boostOrds;
|
||||||
protected int nullDoc = -1;
|
protected int nullDoc = -1;
|
||||||
protected boolean needsScores;
|
protected boolean needsScores;
|
||||||
protected boolean max;
|
protected boolean max;
|
||||||
|
@ -709,7 +727,8 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
int nullPolicy,
|
int nullPolicy,
|
||||||
boolean max,
|
boolean max,
|
||||||
boolean needsScores,
|
boolean needsScores,
|
||||||
IntOpenHashSet boostDocs) {
|
IntOpenHashSet boostDocs,
|
||||||
|
SortedDocValues values) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.nullPolicy = nullPolicy;
|
this.nullPolicy = nullPolicy;
|
||||||
this.max = max;
|
this.max = max;
|
||||||
|
@ -717,11 +736,19 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
this.collapsedSet = new FixedBitSet(maxDoc);
|
this.collapsedSet = new FixedBitSet(maxDoc);
|
||||||
this.boostDocs = boostDocs;
|
this.boostDocs = boostDocs;
|
||||||
if(this.boostDocs != null) {
|
if(this.boostDocs != null) {
|
||||||
|
IntOpenHashSet boostG = new IntOpenHashSet();
|
||||||
Iterator<IntCursor> it = boostDocs.iterator();
|
Iterator<IntCursor> it = boostDocs.iterator();
|
||||||
while(it.hasNext()) {
|
while(it.hasNext()) {
|
||||||
IntCursor cursor = it.next();
|
IntCursor cursor = it.next();
|
||||||
this.collapsedSet.set(cursor.value);
|
int i = cursor.value;
|
||||||
|
this.collapsedSet.set(i);
|
||||||
|
int ord = values.getOrd(i);
|
||||||
|
if(ord > -1) {
|
||||||
|
boostG.add(ord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.boostOrds = boostG.toArray();
|
||||||
|
Arrays.sort(this.boostOrds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,6 +757,12 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
this.collapsedSet.set(nullDoc);
|
this.collapsedSet.set(nullDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.boostOrds != null) {
|
||||||
|
for(int i=0; i<this.boostOrds.length; i++) {
|
||||||
|
ords[boostOrds[i]] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(int i=0; i<ords.length; i++) {
|
for(int i=0; i<ords.length; i++) {
|
||||||
int doc = ords[i];
|
int doc = ords[i];
|
||||||
if(doc > -1) {
|
if(doc > -1) {
|
||||||
|
@ -770,8 +803,8 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
int[] ords,
|
int[] ords,
|
||||||
boolean max,
|
boolean max,
|
||||||
boolean needsScores,
|
boolean needsScores,
|
||||||
IntOpenHashSet boostDocs) throws IOException {
|
IntOpenHashSet boostDocs, SortedDocValues values) throws IOException {
|
||||||
super(maxDoc, field, nullPolicy, max, needsScores, boostDocs);
|
super(maxDoc, field, nullPolicy, max, needsScores, boostDocs, values);
|
||||||
this.ords = ords;
|
this.ords = ords;
|
||||||
this.ordVals = new int[ords.length];
|
this.ordVals = new int[ords.length];
|
||||||
Arrays.fill(ords, -1);
|
Arrays.fill(ords, -1);
|
||||||
|
@ -838,8 +871,8 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
int[] ords,
|
int[] ords,
|
||||||
boolean max,
|
boolean max,
|
||||||
boolean needsScores,
|
boolean needsScores,
|
||||||
IntOpenHashSet boostDocs) throws IOException {
|
IntOpenHashSet boostDocs, SortedDocValues values) throws IOException {
|
||||||
super(maxDoc, field, nullPolicy, max, needsScores, boostDocs);
|
super(maxDoc, field, nullPolicy, max, needsScores, boostDocs, values);
|
||||||
this.ords = ords;
|
this.ords = ords;
|
||||||
this.ordVals = new long[ords.length];
|
this.ordVals = new long[ords.length];
|
||||||
Arrays.fill(ords, -1);
|
Arrays.fill(ords, -1);
|
||||||
|
@ -907,8 +940,8 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
int[] ords,
|
int[] ords,
|
||||||
boolean max,
|
boolean max,
|
||||||
boolean needsScores,
|
boolean needsScores,
|
||||||
IntOpenHashSet boostDocs) throws IOException {
|
IntOpenHashSet boostDocs, SortedDocValues values) throws IOException {
|
||||||
super(maxDoc, field, nullPolicy, max, needsScores, boostDocs);
|
super(maxDoc, field, nullPolicy, max, needsScores, boostDocs, values);
|
||||||
this.ords = ords;
|
this.ords = ords;
|
||||||
this.ordVals = new float[ords.length];
|
this.ordVals = new float[ords.length];
|
||||||
Arrays.fill(ords, -1);
|
Arrays.fill(ords, -1);
|
||||||
|
@ -982,8 +1015,8 @@ public class CollapsingQParserPlugin extends QParserPlugin {
|
||||||
boolean max,
|
boolean max,
|
||||||
boolean needsScores,
|
boolean needsScores,
|
||||||
IntOpenHashSet boostDocs,
|
IntOpenHashSet boostDocs,
|
||||||
FunctionQuery funcQuery, IndexSearcher searcher) throws IOException {
|
FunctionQuery funcQuery, IndexSearcher searcher, SortedDocValues values) throws IOException {
|
||||||
super(maxDoc, null, nullPolicy, max, needsScores, boostDocs);
|
super(maxDoc, null, nullPolicy, max, needsScores, boostDocs, values);
|
||||||
this.valueSource = funcQuery.getValueSource();
|
this.valueSource = funcQuery.getValueSource();
|
||||||
this.rcontext = ValueSource.newContext(searcher);
|
this.rcontext = ValueSource.newContext(searcher);
|
||||||
this.ords = ords;
|
this.ords = ords;
|
||||||
|
|
|
@ -23,9 +23,11 @@ import org.apache.solr.common.params.ModifiableSolrParams;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import com.carrotsearch.hppc.IntOpenHashSet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
|
public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
|
@ -146,6 +148,51 @@ public class TestCollapseQParserPlugin extends SolrTestCaseJ4 {
|
||||||
"//result/doc[3]/float[@name='id'][.='3.0']",
|
"//result/doc[3]/float[@name='id'][.='3.0']",
|
||||||
"//result/doc[4]/float[@name='id'][.='6.0']");
|
"//result/doc[4]/float[@name='id'][.='6.0']");
|
||||||
|
|
||||||
|
//Test SOLR-5773 with score collapse criteria
|
||||||
|
params = new ModifiableSolrParams();
|
||||||
|
params.add("q", "YYYY");
|
||||||
|
params.add("fq", "{!collapse field=group_s nullPolicy=collapse}");
|
||||||
|
params.add("defType", "edismax");
|
||||||
|
params.add("bf", "field(test_ti)");
|
||||||
|
params.add("qf", "term_s");
|
||||||
|
params.add("qt", "/elevate");
|
||||||
|
params.add("elevateIds", "1,5");
|
||||||
|
assertQ(req(params), "*[count(//doc)=3]",
|
||||||
|
"//result/doc[1]/float[@name='id'][.='1.0']",
|
||||||
|
"//result/doc[2]/float[@name='id'][.='5.0']",
|
||||||
|
"//result/doc[3]/float[@name='id'][.='3.0']");
|
||||||
|
|
||||||
|
//Test SOLR-5773 with max field collapse criteria
|
||||||
|
params = new ModifiableSolrParams();
|
||||||
|
params.add("q", "YYYY");
|
||||||
|
params.add("fq", "{!collapse field=group_s min=test_ti nullPolicy=collapse}");
|
||||||
|
params.add("defType", "edismax");
|
||||||
|
params.add("bf", "field(test_ti)");
|
||||||
|
params.add("qf", "term_s");
|
||||||
|
params.add("qt", "/elevate");
|
||||||
|
params.add("elevateIds", "1,5");
|
||||||
|
assertQ(req(params), "*[count(//doc)=3]",
|
||||||
|
"//result/doc[1]/float[@name='id'][.='1.0']",
|
||||||
|
"//result/doc[2]/float[@name='id'][.='5.0']",
|
||||||
|
"//result/doc[3]/float[@name='id'][.='4.0']");
|
||||||
|
|
||||||
|
|
||||||
|
//Test SOLR-5773 elevating documents with null group
|
||||||
|
params = new ModifiableSolrParams();
|
||||||
|
params.add("q", "YYYY");
|
||||||
|
params.add("fq", "{!collapse field=group_s}");
|
||||||
|
params.add("defType", "edismax");
|
||||||
|
params.add("bf", "field(test_ti)");
|
||||||
|
params.add("qf", "term_s");
|
||||||
|
params.add("qt", "/elevate");
|
||||||
|
params.add("elevateIds", "3,4");
|
||||||
|
assertQ(req(params), "*[count(//doc)=4]",
|
||||||
|
"//result/doc[1]/float[@name='id'][.='3.0']",
|
||||||
|
"//result/doc[2]/float[@name='id'][.='4.0']",
|
||||||
|
"//result/doc[3]/float[@name='id'][.='2.0']",
|
||||||
|
"//result/doc[4]/float[@name='id'][.='6.0']");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Test collapse by min int field and sort
|
//Test collapse by min int field and sort
|
||||||
params = new ModifiableSolrParams();
|
params = new ModifiableSolrParams();
|
||||||
|
|
Loading…
Reference in New Issue