mirror of https://github.com/apache/lucene.git
SOLR-6781: Bugfix- BBoxField didn't support dynamic fields.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1641522 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
305a48f3da
commit
f60f243b17
|
@ -433,6 +433,8 @@ Bug Fixes
|
||||||
|
|
||||||
* SOLR-6684: Fix-up /export JSON. (Joel Bernstein)
|
* SOLR-6684: Fix-up /export JSON. (Joel Bernstein)
|
||||||
|
|
||||||
|
* SOLR-6781: BBoxField didn't support dynamic fields. (David Smiley)
|
||||||
|
|
||||||
================== 4.10.2 ==================
|
================== 4.10.2 ==================
|
||||||
|
|
||||||
Bug Fixes
|
Bug Fixes
|
||||||
|
|
|
@ -34,8 +34,8 @@ import java.util.Map;
|
||||||
public class BBoxField extends AbstractSpatialFieldType<BBoxStrategy> implements SchemaAware {
|
public class BBoxField extends AbstractSpatialFieldType<BBoxStrategy> implements SchemaAware {
|
||||||
private static final String PARAM_QUERY_TARGET_PROPORTION = "queryTargetProportion";
|
private static final String PARAM_QUERY_TARGET_PROPORTION = "queryTargetProportion";
|
||||||
private static final String PARAM_MIN_SIDE_LENGTH = "minSideLength";
|
private static final String PARAM_MIN_SIDE_LENGTH = "minSideLength";
|
||||||
private String numberFieldName;//required
|
private String numberTypeName;//required
|
||||||
private String booleanFieldName = "boolean";
|
private String booleanTypeName = "boolean";
|
||||||
|
|
||||||
private IndexSchema schema;
|
private IndexSchema schema;
|
||||||
|
|
||||||
|
@ -48,25 +48,25 @@ public class BBoxField extends AbstractSpatialFieldType<BBoxStrategy> implements
|
||||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "The field type: " + typeName
|
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "The field type: " + typeName
|
||||||
+ " must specify the numberType attribute.");
|
+ " must specify the numberType attribute.");
|
||||||
}
|
}
|
||||||
numberFieldName = v;
|
numberTypeName = v;
|
||||||
|
|
||||||
v = args.remove("booleanType");
|
v = args.remove("booleanType");
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
booleanFieldName = v;
|
booleanTypeName = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inform(IndexSchema schema) {
|
public void inform(IndexSchema schema) {
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
FieldType numberType = schema.getFieldTypeByName(numberFieldName);
|
FieldType numberType = schema.getFieldTypeByName(numberTypeName);
|
||||||
FieldType booleanType = schema.getFieldTypeByName(booleanFieldName);
|
FieldType booleanType = schema.getFieldTypeByName(booleanTypeName);
|
||||||
|
|
||||||
if (numberType == null) {
|
if (numberType == null) {
|
||||||
throw new RuntimeException("Cannot find number fieldType: " + numberFieldName);
|
throw new RuntimeException("Cannot find number fieldType: " + numberTypeName);
|
||||||
}
|
}
|
||||||
if (booleanType == null) {
|
if (booleanType == null) {
|
||||||
throw new RuntimeException("Cannot find boolean fieldType: " + booleanFieldName);
|
throw new RuntimeException("Cannot find boolean fieldType: " + booleanTypeName);
|
||||||
}
|
}
|
||||||
if (!(booleanType instanceof BoolField)) {
|
if (!(booleanType instanceof BoolField)) {
|
||||||
throw new RuntimeException("Must be a BoolField: " + booleanType);
|
throw new RuntimeException("Must be a BoolField: " + booleanType);
|
||||||
|
@ -75,33 +75,47 @@ public class BBoxField extends AbstractSpatialFieldType<BBoxStrategy> implements
|
||||||
throw new RuntimeException("Must be TrieDoubleField: " + numberType);
|
throw new RuntimeException("Must be TrieDoubleField: " + numberType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//note: this only works for explicit fields, not dynamic fields
|
||||||
List<SchemaField> fields = new ArrayList<>(schema.getFields().values());//copy, because we modify during iteration
|
List<SchemaField> fields = new ArrayList<>(schema.getFields().values());//copy, because we modify during iteration
|
||||||
for (SchemaField sf : fields) {
|
for (SchemaField sf : fields) {
|
||||||
if (sf.getType() == this) {
|
if (sf.getType() == this) {
|
||||||
String name = sf.getName();
|
String name = sf.getName();
|
||||||
|
registerSubFields(schema, name, numberType, booleanType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerSubFields(IndexSchema schema, String name, FieldType numberType, FieldType booleanType) {
|
||||||
register(schema, name + BBoxStrategy.SUFFIX_MINX, numberType);
|
register(schema, name + BBoxStrategy.SUFFIX_MINX, numberType);
|
||||||
register(schema, name + BBoxStrategy.SUFFIX_MAXX, numberType);
|
register(schema, name + BBoxStrategy.SUFFIX_MAXX, numberType);
|
||||||
register(schema, name + BBoxStrategy.SUFFIX_MINY, numberType);
|
register(schema, name + BBoxStrategy.SUFFIX_MINY, numberType);
|
||||||
register(schema, name + BBoxStrategy.SUFFIX_MAXY, numberType);
|
register(schema, name + BBoxStrategy.SUFFIX_MAXY, numberType);
|
||||||
register(schema, name + BBoxStrategy.SUFFIX_XDL, booleanType);
|
register(schema, name + BBoxStrategy.SUFFIX_XDL, booleanType);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// note: Registering the field is probably optional; it makes it show up in the schema browser and may have other
|
||||||
|
// benefits.
|
||||||
private void register(IndexSchema schema, String name, FieldType fieldType) {
|
private void register(IndexSchema schema, String name, FieldType fieldType) {
|
||||||
SchemaField sf = new SchemaField(name, fieldType);
|
SchemaField sf = new SchemaField(name, fieldType);
|
||||||
schema.getFields().put(sf.getName(), sf);
|
schema.getFields().put(sf.getName(), sf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BBoxStrategy newSpatialStrategy(String s) {
|
protected BBoxStrategy newSpatialStrategy(String fieldName) {
|
||||||
BBoxStrategy strategy = new BBoxStrategy(ctx, s);
|
//if it's a dynamic field, we register the sub-fields now.
|
||||||
|
FieldType numberType = schema.getFieldTypeByName(numberTypeName);
|
||||||
|
FieldType booleanType = schema.getFieldTypeByName(booleanTypeName);
|
||||||
|
if (schema.isDynamicField(fieldName)) {
|
||||||
|
registerSubFields(schema, fieldName, numberType, booleanType);
|
||||||
|
}
|
||||||
|
|
||||||
|
BBoxStrategy strategy = new BBoxStrategy(ctx, fieldName);
|
||||||
//Solr's FieldType ought to expose Lucene FieldType. Instead as a hack we create a Field with a dummy value.
|
//Solr's FieldType ought to expose Lucene FieldType. Instead as a hack we create a Field with a dummy value.
|
||||||
SchemaField field = schema.getField(strategy.getFieldName() + BBoxStrategy.SUFFIX_MINX);
|
final SchemaField solrNumField = new SchemaField("_", numberType);//dummy temp
|
||||||
org.apache.lucene.document.FieldType luceneType =
|
org.apache.lucene.document.FieldType luceneType =
|
||||||
(org.apache.lucene.document.FieldType) field.createField(0.0, 1.0f).fieldType();
|
(org.apache.lucene.document.FieldType) solrNumField.createField(0.0, 1.0f).fieldType();
|
||||||
//and annoyingly this field isn't going to have a docValues format because Solr uses a separate Field for that
|
//and annoyingly this Field isn't going to have a docValues format because Solr uses a separate Field for that
|
||||||
if (field.hasDocValues()) {
|
if (solrNumField.hasDocValues()) {
|
||||||
luceneType = new org.apache.lucene.document.FieldType(luceneType);
|
luceneType = new org.apache.lucene.document.FieldType(luceneType);
|
||||||
luceneType.setDocValuesType(DocValuesType.NUMERIC);
|
luceneType.setDocValuesType(DocValuesType.NUMERIC);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
<field name="pointvector" type="pointvector" />
|
<field name="pointvector" type="pointvector" />
|
||||||
<field name="bbox" type="bbox" />
|
<field name="bbox" type="bbox" />
|
||||||
|
|
||||||
|
<dynamicField name="bboxD_*" type="bbox" indexed="true" />
|
||||||
|
|
||||||
</fields>
|
</fields>
|
||||||
|
|
||||||
<uniqueKey>id</uniqueKey>
|
<uniqueKey>id</uniqueKey>
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class TestSolr4Spatial2 extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBBox() throws Exception {
|
public void testBBox() throws Exception {
|
||||||
String fieldName = "bbox";
|
String fieldName = random().nextBoolean() ? "bbox" : "bboxD_dynamic";
|
||||||
assertU(adoc("id", "0"));//nothing
|
assertU(adoc("id", "0"));//nothing
|
||||||
assertU(adoc("id", "1", fieldName, "ENVELOPE(-10, 20, 15, 10)"));
|
assertU(adoc("id", "1", fieldName, "ENVELOPE(-10, 20, 15, 10)"));
|
||||||
assertU(adoc("id", "2", fieldName, "ENVELOPE(22, 22, 10, 10)"));//pt
|
assertU(adoc("id", "2", fieldName, "ENVELOPE(22, 22, 10, 10)"));//pt
|
||||||
|
@ -48,14 +48,16 @@ public class TestSolr4Spatial2 extends SolrTestCaseJ4 {
|
||||||
assertJQ(req("q", "{!field f="+fieldName+" filter=false score=overlapRatio " +
|
assertJQ(req("q", "{!field f="+fieldName+" filter=false score=overlapRatio " +
|
||||||
"queryTargetProportion=0.25}" +
|
"queryTargetProportion=0.25}" +
|
||||||
"Intersects(ENVELOPE(10,25,12,10))",
|
"Intersects(ENVELOPE(10,25,12,10))",
|
||||||
"fl", "id,score",
|
"fl", "*,score",
|
||||||
"debug", "results"),//explain info
|
"debug", "results"),//explain info
|
||||||
"/response/docs/[0]/id=='2'",
|
"/response/docs/[0]/id=='2'",
|
||||||
"/response/docs/[0]/score==0.75]",
|
"/response/docs/[0]/score==0.75]",
|
||||||
"/response/docs/[1]/id=='1'",
|
"/response/docs/[1]/id=='1'",
|
||||||
"/response/docs/[1]/score==0.26666668]",
|
"/response/docs/[1]/score==0.26666668]",
|
||||||
"/response/docs/[2]/id=='0'",
|
"/response/docs/[2]/id=='0'",
|
||||||
"/response/docs/[2]/score==0.0"
|
"/response/docs/[2]/score==0.0",
|
||||||
|
|
||||||
|
"/response/docs/[1]/" + fieldName + "=='ENVELOPE(-10, 20, 15, 10)'"//stored value
|
||||||
);
|
);
|
||||||
|
|
||||||
//minSideLength with point query
|
//minSideLength with point query
|
||||||
|
|
Loading…
Reference in New Issue