SOLR-1131: first pass at fixing support for subFieldSuffix (index + search)

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@893792 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2009-12-24 17:42:48 +00:00
parent 74d642d818
commit 62b1873e30
4 changed files with 37 additions and 112 deletions

View File

@ -407,7 +407,7 @@
The subFields are an implementation detail of the fieldType, and end
users normally should not need to know about them.
-->
<fieldType name="location" class="solr.PointType" dimension="2" subFieldType="double"/>
<fieldType name="location" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
</types>

View File

@ -55,7 +55,7 @@ public abstract class CoordinateFieldType extends FieldType implements SchemaAwa
protected FieldType subType;
public static final String SUB_FIELD_SUFFIX = "subFieldSuffix";
public static final String SUB_FIELD_TYPE = "subFieldType";
private String suffix;//need to keep this around between init and inform, since dynamic fields aren't created until before inform
protected String suffix;
protected int dynFieldProps;
public int getDimension() {
@ -76,6 +76,7 @@ public abstract class CoordinateFieldType extends FieldType implements SchemaAwa
if (subFT != null) {
args.remove(SUB_FIELD_TYPE);
subType = schema.getFieldTypeByName(subFT.trim());
suffix = POLY_FIELD_SEPARATOR + subType.typeName;
} else if (subSuffix != null) {
args.remove(SUB_FIELD_SUFFIX);
suffix = subSuffix;
@ -90,18 +91,9 @@ public abstract class CoordinateFieldType extends FieldType implements SchemaAwa
public void inform(IndexSchema schema) {
//Can't do this until here b/c the Dynamic Fields are not initialized until here.
if (suffix != null){
SchemaField sf = schema.getField(suffix);
subType = sf.getType();//this means it is already registered
dynFieldProps = sf.getProperties();
}
else if (subType != null) {
if (subType != null) {
SchemaField proto = registerPolyFieldDynamicPrototype(schema, subType);
dynFieldProps = proto.getProperties();
} else {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "The field type: " + typeName
+ " must specify the " +
SUB_FIELD_TYPE + " attribute or the " + SUB_FIELD_SUFFIX + " attribute.");
}
}

View File

@ -242,72 +242,6 @@ public abstract class FieldType extends FieldProperties {
}
/**
* Create multiple fields from a single field and multiple values. Fields are named as SchemaField.getName() + {@link #POLY_FIELD_SEPARATOR} + i, where
* i starts at 0.
* <p/>
* If the field is stored, then an extra field gets created that contains the storageVal. It is this field that also
*
* @param field The {@link org.apache.solr.schema.SchemaField}
* @param props The properties to use
* @param delegatedType An optional type to use. If null, then field.getType() is used. Useful for poly fields.
* @param storageVal If the field stores, then this value will be used for the stored field
* @param boost The boost to apply to all fields
* @param externalVals The values to use
* @return The fields
*/
protected Fieldable[] createFields(SchemaField field, int props,
FieldType delegatedType, String storageVal,
float boost, String ... externalVals) {
int n = field.indexed() ? externalVals.length : 0;
n += field.stored() ? 1 : 0;
if (delegatedType == null) { //if the type isn't being overriden, then just use the base one
delegatedType = field.getType();
}
Field[] results = new Field[n];
//Field.Store.NO,Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO, true, true
if (externalVals.length > 0) {
if (field.indexed()) {
String name = field.getName() + "_";
String suffix = POLY_FIELD_SEPARATOR + delegatedType.typeName;
int len = name.length();
StringBuilder bldr = new StringBuilder(len + 3 + suffix.length());//should be enough buffer to handle most values of j.
bldr.append(name);
for (int j = 0; j < externalVals.length; j++) {
//SchemaField is final, as is name, so we need to recreate each time
//put the counter before the separator, b/c dynamic fields can't be asterisks on both the front and the end of the String
bldr.append(j).append(suffix);
SchemaField sf = SchemaField.create(bldr.toString(),
delegatedType, props, null);
//schema.getDynamicField(name + "_" + j + POLY_FIELD_SEPARATOR + delegatedType.typeName);
/**/
//new SchemaField(name, ft, p, defaultValue )
//QUESTION: should we allow for vectors, etc? Not sure that it makes sense
results[j] = delegatedType.createField(sf, externalVals[j], boost);
bldr.setLength(len);//cut the builder back to just the length of the prefix, but keep the capacity
}
}
Field.TermVector fieldTermVec = getFieldTermVec(field, storageVal);
if (field.stored() || fieldTermVec.equals(Field.TermVector.YES)
|| fieldTermVec.equals(Field.TermVector.WITH_OFFSETS)
|| fieldTermVec.equals(Field.TermVector.WITH_POSITIONS)
|| fieldTermVec.equals(Field.TermVector.WITH_POSITIONS_OFFSETS)
) {
//QUESTION: should we allow for vectors, etc? Not sure that it makes sense
results[results.length - 1] = createField(field.getName(), storageVal, getFieldStore(field, storageVal),
Field.Index.NO,
fieldTermVec, field.omitNorms(), field.omitTf(), boost);
}
}
return results;
}
/**
* Create the field from native Lucene parts. Mostly intended for use by FieldTypes outputing multiple
* Fields per SchemaField

View File

@ -54,7 +54,7 @@ public class PointType extends CoordinateFieldType {
public static final String DIMENSION = "dimension";
protected IndexSchema schema; // needed for retrieving SchemaFields
protected String[] suffixes;
@Override
protected void init(IndexSchema schema, Map<String, String> args) {
@ -68,6 +68,15 @@ public class PointType extends CoordinateFieldType {
this.schema = schema;
super.init(schema, args);
// cache suffixes
suffixes = new String[dimension];
for (int i=0; i<dimension; i++) {
suffixes[i] = "_" + i + suffix;
}
}
protected SchemaField subField(SchemaField base, int i) {
return schema.getField(base.getName() + suffixes[i]);
}
@ -79,7 +88,24 @@ public class PointType extends CoordinateFieldType {
@Override
public Fieldable[] createFields(SchemaField field, String externalVal, float boost) {
String[] point = DistanceUtils.parsePoint(null, externalVal, dimension);
return createFields(field, dynFieldProps, subType, externalVal, boost, point);
// TODO: this doesn't currently support polyFields as sub-field types
Fieldable[] f = new Fieldable[ (field.indexed() ? dimension : 0) + (field.stored() ? 1 : 0) ];
if (field.indexed()) {
for (int i=0; i<dimension; i++) {
f[i] = subField(field, i).createField(point[i], boost);
}
}
if (field.stored()) {
String storedVal = externalVal; // normalize or not?
f[f.length - 1] = createField(field.getName(), storedVal,
getFieldStore(field, storedVal), Field.Index.NO, Field.TermVector.NO,
false, false, boost);
}
return f;
}
@Override
@ -119,50 +145,25 @@ public class PointType extends CoordinateFieldType {
String[] p1 = DistanceUtils.parsePoint(null, part1, dimension);
String[] p2 = DistanceUtils.parsePoint(null, part2, dimension);
BooleanQuery result = new BooleanQuery(true);
String name = field.getName() + "_";
String suffix = POLY_FIELD_SEPARATOR + subType.typeName;
int len = name.length();
StringBuilder bldr = new StringBuilder(len + 3 + suffix.length());//should be enough buffer to handle most values of j.
bldr.append(name);
for (int i = 0; i < dimension; i++) {
bldr.append(i).append(suffix);
SchemaField subSF = schema.getField(bldr.toString());
SchemaField subSF = subField(field, i);
// points must currently be ordered... should we support specifying any two opposite corner points?
/*new TermRangeQuery(
field.getName() + i + POLY_FIELD_SEPARATOR + subType.typeName,
subType.toInternal(p1[i]),
subType.toInternal(p2[i]),
minInclusive, maxInclusive);*/
result.add(subType.getRangeQuery(parser, subSF, p1[i], p2[i], minInclusive, maxInclusive), BooleanClause.Occur.MUST);
bldr.setLength(len);
result.add(subSF.getType().getRangeQuery(parser, subSF, p1[i], p2[i], minInclusive, maxInclusive), BooleanClause.Occur.MUST);
}
return result;
}
@Override
public Query getFieldQuery(QParser parser, SchemaField field, String externalVal) {
Query result = null;
String[] p1 = DistanceUtils.parsePoint(null, externalVal, dimension);
//TODO: should we assert that p1.length == dimension?
BooleanQuery bq = new BooleanQuery(true);
String name = field.getName() + "_";
String suffix = POLY_FIELD_SEPARATOR + subType.typeName;
int len = name.length();
StringBuilder bldr = new StringBuilder(len + 3 + suffix.length());//should be enough buffer to handle most values of j.
bldr.append(name);
for (int i = 0; i < dimension; i++) {
bldr.append(i).append(suffix);
SchemaField sf1 = schema.getField(bldr.toString());
Query tq = subType.getFieldQuery(parser, sf1, p1[i]);
//new TermQuery(new Term(bldr.toString(), subType.toInternal(p1[i])));
SchemaField sf = subField(field, i);
Query tq = sf.getType().getFieldQuery(parser, sf, p1[i]);
bq.add(tq, BooleanClause.Occur.MUST);
bldr.setLength(len);
}
result = bq;
return result;
return bq;
}
class PointTypeValueSource extends MultiValueSource {
@ -272,5 +273,3 @@ public class PointType extends CoordinateFieldType {
}
}