SOLR-9993: Add support for ExpandComponent with PointFields

This commit is contained in:
Cao Manh Dat 2017-03-29 13:52:51 +07:00
parent deddc9b5c8
commit 9b7c8d5606
3 changed files with 53 additions and 26 deletions

View File

@ -128,6 +128,8 @@ New Features
* SOLR-10349: Add totalTermFreq support to TermsComponent. (Shai Erera)
* SOLR-9993: Add support for ExpandComponent with PointFields. (Cao Manh Dat)
Optimizations
----------------------

View File

@ -73,7 +73,12 @@ import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.DoublePointField;
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.SchemaField;
import org.apache.solr.schema.StrField;
import org.apache.solr.schema.TrieDoubleField;
import org.apache.solr.schema.TrieFloatField;
@ -209,7 +214,8 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
SolrIndexSearcher searcher = req.getSearcher();
LeafReader reader = searcher.getSlowAtomicReader();
FieldType fieldType = searcher.getSchema().getField(field).getType();
SchemaField schemaField = searcher.getSchema().getField(field);
FieldType fieldType = schemaField.getType();
SortedDocValues values = null;
long nullValue = 0;
@ -228,17 +234,18 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
//Get the nullValue for the numeric collapse field
String defaultValue = searcher.getSchema().getField(field).getDefaultValue();
if(defaultValue != null) {
if(fieldType instanceof TrieIntField || fieldType instanceof TrieLongField) {
if(fieldType instanceof TrieIntField || fieldType instanceof TrieLongField ||
fieldType instanceof IntPointField || fieldType instanceof LongPointField) {
nullValue = Long.parseLong(defaultValue);
} else if(fieldType instanceof TrieFloatField){
} else if(fieldType instanceof TrieFloatField || fieldType instanceof FloatPointField){
nullValue = Float.floatToIntBits(Float.parseFloat(defaultValue));
} else if(fieldType instanceof TrieDoubleField){
} else if(fieldType instanceof TrieDoubleField || fieldType instanceof DoublePointField){
nullValue = Double.doubleToLongBits(Double.parseDouble(defaultValue));
}
} else {
if(fieldType instanceof TrieFloatField){
if(fieldType instanceof TrieFloatField || fieldType instanceof FloatPointField){
nullValue = Float.floatToIntBits(0.0f);
} else if(fieldType instanceof TrieDoubleField){
} else if(fieldType instanceof TrieDoubleField || fieldType instanceof DoublePointField){
nullValue = Double.doubleToLongBits(0.0f);
}
}
@ -369,7 +376,11 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
}
if(count > 0 && count < 200) {
groupQuery = getGroupQuery(field, fieldType, count, groupSet);
if (fieldType.isPointField()) {
groupQuery = getPointGroupQuery(schemaField, count, groupSet);
} else {
groupQuery = getGroupQuery(field, fieldType, count, groupSet);
}
}
}
@ -442,13 +453,7 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
String group = charsRef.toString();
outMap.add(group, slice);
} else {
if(fieldType instanceof TrieIntField || fieldType instanceof TrieLongField ) {
outMap.add(Long.toString(groupValue), slice);
} else if(fieldType instanceof TrieFloatField) {
outMap.add(Float.toString(Float.intBitsToFloat((int) groupValue)), slice);
} else if(fieldType instanceof TrieDoubleField) {
outMap.add(Double.toString(Double.longBitsToDouble(groupValue)), slice);
}
outMap.add(numericToString(fieldType, groupValue), slice);
}
}
}
@ -703,18 +708,10 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
BytesRefBuilder term = new BytesRefBuilder();
Iterator<LongCursor> it = groupSet.iterator();
int index = -1;
String stringVal = null;
while (it.hasNext()) {
LongCursor cursor = it.next();
if(ft instanceof TrieIntField || ft instanceof TrieLongField) {
stringVal = Long.toString(cursor.value);
} else {
if(ft instanceof TrieFloatField) {
stringVal = Float.toString(Float.intBitsToFloat((int)cursor.value));
} else {
stringVal = Double.toString(Double.longBitsToDouble(cursor.value));
}
}
String stringVal = numericToString(ft, cursor.value);
ft.readableToIndexed(stringVal, term);
bytesRefs[++index] = term.toBytesRef();
}
@ -722,6 +719,36 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
return new SolrConstantScoreQuery(new QueryWrapperFilter(new TermInSetQuery(fname, bytesRefs)));
}
private Query getPointGroupQuery(SchemaField sf,
int size,
LongHashSet groupSet) {
Iterator<LongCursor> it = groupSet.iterator();
List<String> values = new ArrayList<>(size);
FieldType ft = sf.getType();
while (it.hasNext()) {
LongCursor cursor = it.next();
values.add(numericToString(ft, cursor.value));
}
return new SolrConstantScoreQuery(new QueryWrapperFilter(sf.getType().getSetQuery(null, sf, values)));
}
private String numericToString(FieldType fieldType, long val) {
if (fieldType.getNumberType() != null) {
switch (fieldType.getNumberType()) {
case INTEGER:
case LONG:
return Long.toString(val);
case FLOAT:
return Float.toString(Float.intBitsToFloat((int)val));
case DOUBLE:
return Double.toString(Double.longBitsToDouble(val));
}
}
throw new IllegalArgumentException("FieldType must be INT,LONG,FLOAT,DOUBLE found " + fieldType);
}
private Query getGroupQuery(String fname,
int size,
IntObjectHashMap<BytesRef> ordBytes) throws Exception {

View File

@ -21,14 +21,12 @@ import java.util.Collections;
import java.util.List;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.SolrTestCaseJ4.SuppressPointFields;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.search.CollapsingQParserPlugin;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@SuppressPointFields
public class TestExpandComponent extends SolrTestCaseJ4 {
@BeforeClass