SOLR-82 - allow default field values to be specified in the schema.xml

git-svn-id: https://svn.apache.org/repos/asf/incubator/solr/trunk@493170 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2007-01-05 20:12:18 +00:00
parent 4202fc353f
commit 21b830ba5c
9 changed files with 96 additions and 13 deletions

View File

@ -35,7 +35,8 @@ Detailed Change List
--------------------
New Features
1.
1. SOLR-82: Default field values can be specified in the schema.xml.
(Ryan McKinley via hossman)
Changes in runtime behavior
1. Highlighting using DisMax will only pick up terms from the main
@ -54,7 +55,7 @@ Bug Fixes
Other Changes
1.
================== Release 1.1.0, YYYYMMDD ==================
================== Release 1.1.0, 20061222 ==================
Status
------

View File

@ -35,7 +35,7 @@
<field name="features">tag with escaped chars: &lt;nicetag/&gt;</field>
<field name="features">escaped ampersand: Bonnie &amp; Clyde</field>
<field name="price">0</field>
<field name="popularity">10</field>
<!-- no popularity, get the default from schema.xml -->
<field name="inStock">true</field>
</doc>
</add>

View File

@ -211,7 +211,10 @@
<field name="weight" type="sfloat" indexed="true" stored="true"/>
<field name="price" type="sfloat" indexed="true" stored="true"/>
<field name="popularity" type="sint" indexed="true" stored="true"/>
<!-- "default" values can be specified for fields, indicating which
value should be used if no value is specified when adding a document.
-->
<field name="popularity" type="sint" indexed="true" stored="true" default="0"/>
<field name="inStock" type="boolean" indexed="true" stored="true"/>
<!-- catchall field, containing all other searchable text fields (implemented
@ -222,6 +225,11 @@
results by manufacturer. copied from "manu" via copyField -->
<field name="manu_exact" type="string" indexed="true" stored="false"/>
<!-- Here, default is used to create a "timestamp" field indicating
When each document was indexed.
-->
<field name="timestamp" type="date" indexed="true" stored="true" default="NOW" multiValued="false"/>
<!-- Dynamic field definitions. If a field name is not found, dynamicFields
will be used if the name matches any of the patterns.

View File

@ -88,6 +88,7 @@ public final class IndexSchema {
private final HashMap<String, SchemaField> fields = new HashMap<String,SchemaField>();
private final HashMap<String, FieldType> fieldTypes = new HashMap<String,FieldType>();
private final List<SchemaField> fieldsWithDefaultValue = new ArrayList<SchemaField>();
/**
* Provides direct access to the Map containing all explicit
@ -109,6 +110,10 @@ public final class IndexSchema {
*/
public Map<String,FieldType> getFieldTypes() { return fieldTypes; }
/**
* Provides direct access to the List containing all fields with a default value
*/
public List<SchemaField> getFieldsWithDefaultValue() { return fieldsWithDefaultValue; }
private Similarity similarity;
@ -335,6 +340,10 @@ public final class IndexSchema {
if (node.getNodeName().equals("field")) {
fields.put(f.getName(),f);
log.fine("field defined: " + f);
if( f.getDefaultValue() != null ) {
log.fine(name+" contains default value: " + f.getDefaultValue());
fieldsWithDefaultValue.add( f );
}
} else if (node.getNodeName().equals("dynamicField")) {
dFields.add(new DynamicField(f));
log.fine("dynamic field defined: " + f);

View File

@ -36,20 +36,21 @@ public final class SchemaField extends FieldProperties {
final String name;
final FieldType type;
final int properties;
final String defaultValue;
/** Create a new SchemaField with the given name and type,
* using all the default properties from the type.
*/
public SchemaField(String name, FieldType type) {
this(name, type, type.properties);
this(name, type, type.properties, null);
}
/** Create a new SchemaField from an existing one by using all
* of the properties of the prototype except the field name.
*/
public SchemaField(SchemaField prototype, String name) {
this(name, prototype.type, prototype.properties);
this(name, prototype.type, prototype.properties, prototype.defaultValue );
}
/** Create a new SchemaField with the given name and type,
@ -58,10 +59,11 @@ public final class SchemaField extends FieldProperties {
* constructor should derive the properties from type.getProperties()
* using all the default properties from the type.
*/
public SchemaField(String name, FieldType type, int properties) {
public SchemaField(String name, FieldType type, int properties, String defaultValue ) {
this.name = name;
this.type = type;
this.properties = properties;
this.defaultValue = defaultValue;
}
public String getName() { return name; }
@ -89,8 +91,9 @@ public final class SchemaField extends FieldProperties {
public String toString() {
return name + "{type="+type.getTypeName()
+ ",properties=" + propertiesToString(properties)
+ "}";
+ ((defaultValue==null)?"":(",default="+defaultValue))
+ ",properties=" + propertiesToString(properties)
+ "}";
}
public void write(XMLWriter writer, String name, Fieldable val) throws IOException {
@ -157,7 +160,15 @@ public final class SchemaField extends FieldProperties {
p &= ~falseProps;
p |= trueProps;
return new SchemaField(name, ft, p);
String defaultValue = null;
if( props.containsKey( "default" ) ) {
defaultValue = (String)props.get( "default" );
}
return new SchemaField(name, ft, p, defaultValue );
}
public String getDefaultValue() {
return defaultValue;
}
}

View File

@ -105,6 +105,14 @@ public class DocumentBuilder {
// specific to this type of document builder
public Document getDoc() {
// Check for default fields in our schema...
for( SchemaField field : schema.getFieldsWithDefaultValue() ) {
if( doc.getField( field.getName() ) == null ) {
doc.add( field.createField( field.getDefaultValue(), 1.0f ) );
}
}
Document ret = doc; doc=null;
return ret;
}

View File

@ -340,6 +340,46 @@ public class BasicFunctionalityTest extends AbstractSolrTestCase {
}
public void testDefaultFieldValues() {
assertU(adoc("id", "4055",
"subject", "Hoss the Hoss man Hostetter"));
assertU(adoc("id", "4056",
"intDefault", "4",
"subject", "Some Other Guy"));
assertU(adoc("id", "4057",
"multiDefault", "a",
"multiDefault", "b",
"subject", "The Dude"));
assertU(commit());
assertQ("everthing should have recent timestamp",
req("timestamp:[NOW-10MINUTES TO NOW]")
,"*[count(//doc)=3]"
,"//date[@name='timestamp']"
);
assertQ("2 docs should have the default for multiDefault",
req("multiDefault:muLti-Default")
,"*[count(//doc)=2]"
,"//arr[@name='multiDefault']"
);
assertQ("1 doc should have it's explicit multiDefault",
req("multiDefault:a")
,"*[count(//doc)=1]"
);
assertQ("2 docs should have the default for intDefault",
req("intDefault:42")
,"*[count(//doc)=2]"
);
assertQ("1 doc should have it's explicit intDefault",
req("intDefault:[3 TO 5]")
,"*[count(//doc)=1]"
);
}
public void testConfigDefaults() {
assertU(adoc("id", "42",
"name", "Zapp Brannigan"));

View File

@ -1118,7 +1118,7 @@ public class ConvertedLegacyTest extends AbstractSolrTestCase {
,"//str[.='Yonik'] "
,"//float[.='1.4142135'] "
,"//float[@name='score'] "
,"*[count(//doc/*)=10]"
,"*[count(//doc/*)=13]"
);
args = new HashMap<String,String>();
args.put("version","2.0");
@ -1129,7 +1129,7 @@ public class ConvertedLegacyTest extends AbstractSolrTestCase {
,"//str[.='Yonik'] "
,"//float[.='1.4142135'] "
,"//float[@name='score'] "
,"*[count(//doc/*)=10]"
,"*[count(//doc/*)=13]"
);
args = new HashMap<String,String>();
args.put("version","2.0");
@ -1139,7 +1139,7 @@ public class ConvertedLegacyTest extends AbstractSolrTestCase {
assertQ(req
,"//str[.='Yonik'] "
,"//float[.='1.4142135'] "
,"*[count(//doc/*)>=9]"
,"*[count(//doc/*)>=12]"
);
// test maxScore

View File

@ -357,7 +357,13 @@
<field name="sku2" type="skutype2" indexed="true" stored="true"/>
<field name="textgap" type="textgap" indexed="true" stored="true"/>
<field name="timestamp" type="date" indexed="true" stored="true" default="NOW" multiValued="false"/>
<field name="multiDefault" type="string" indexed="true" stored="true" default="muLti-Default" multiValued="true"/>
<field name="intDefault" type="sint" indexed="true" stored="true" default="42" multiValued="false"/>
<!-- Dynamic field definitions. If a field name is not found, dynamicFields
will be used if the name matches any of the patterns.
RESTRICTION: the glob-like pattern in the name attribute must have