SOLR-3628: SolrInputField and SolrInputDocument are now consistently backed by Collections passed in to setValue/setField, and defensively copy values from Collections passed to addValue/addField

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1383520 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2012-09-11 18:38:45 +00:00
parent 3f5a6ee44b
commit ee1e747c29
5 changed files with 58 additions and 9 deletions

View File

@ -140,6 +140,11 @@ Bug Fixes
* SOLR-3518: Include final 'hits' in log information when aggregating a
distibuted request (Markus Jelsma via hossman)
* SOLR-3628: SolrInputField and SolrInputDocument are now consistently backed
by Collections passed in to setValue/setField, and defensively copy values
from Collections passed to addValue/addField
(Tom Switzer via hossman)
Other Changes
----------------------

View File

@ -105,15 +105,24 @@ public class SolrDocument implements Map<String,Object>, Iterable<Map.Entry<Stri
}
/**
* This will add a field to the document. If fields already exist with this name
* it will append the collection
* This will add a field to the document. If fields already exist with this
* name it will append value to the collection. If the value is Collection,
* each value will be added independently.
*/
@SuppressWarnings("unchecked")
public void addField(String name, Object value)
{
Object existing = _fields.get(name);
if (existing == null) {
this.setField( name, value );
if( value instanceof Collection ) {
Collection<Object> c = new ArrayList<Object>( 3 );
for ( Object o : (Collection<Object>)value ) {
c.add(o);
}
this.setField( name, c );
} else {
this.setField( name, value );
}
return;
}

View File

@ -126,8 +126,10 @@ public class SolrInputDocument implements Map<String,SolrInputField>, Iterable<S
}
/**
* Adds a field with the given name, value and boost. If a field with the name already exists, then it is updated to
* the new value and boost.
* Adds a field with the given name, value and boost. If a field with the
* name already exists, then the given value is appended to the value of that
* field, with the new boost. If the value is a collection, then each of its
* values will be added to the field.
*
* @param name Name of the field to add
* @param value Value of the field

View File

@ -41,7 +41,9 @@ public class SolrInputField implements Iterable<Object>, Serializable
//---------------------------------------------------------------
/**
* Set the value for a field. Arrays will be converted to a collection.
* Set the value for a field. Arrays will be converted to a collection. If
* a collection is given, then that collection will be used as the backing
* collection for the values.
*/
public void setValue(Object v, float b) {
boost = b;
@ -60,13 +62,22 @@ public class SolrInputField implements Iterable<Object>, Serializable
}
/**
* Add values to a field. if the added value is a collection, each value
* will be added individually
* Add values to a field. If the added value is a collection, each value
* will be added individually.
*/
@SuppressWarnings("unchecked")
public void addValue(Object v, float b) {
if( value == null ) {
setValue(v, b);
if ( v instanceof Collection ) {
Collection<Object> c = new ArrayList<Object>( 3 );
for ( Object o : (Collection<Object>)v ) {
c.add( o );
}
setValue(c, b);
} else {
setValue(v, b);
}
return;
}

View File

@ -158,6 +158,28 @@ public class SolrDocumentTest extends LuceneTestCase
assertFalse( doc.getFieldValuesMap().containsKey( "g" ) );
assertFalse( doc.getFieldValueMap().keySet().contains( "g" ) );
assertFalse( doc.getFieldValuesMap().keySet().contains( "g" ) );
// A read-only list shouldn't break addField("v", ...).
List<String> ro = Collections.unmodifiableList(c0);
doc = new SolrDocument();
doc.addField( "v", ro );
// This should NOT throw an UnsupportedOperationException.
doc.addField( "v", "asdf" );
// set field using a collection is documented to be backed by
// that collection, so changes should affect it.
Collection<String> tmp = new ArrayList<String>(3);
tmp.add("one");
doc.setField( "collection_backed", tmp );
assertEquals("collection not the same",
tmp, doc.getFieldValues( "collection_backed" ));
tmp.add("two");
assertEquals("wrong size",
2, doc.getFieldValues( "collection_backed" ).size());
assertEquals("collection not the same",
tmp, doc.getFieldValues( "collection_backed" ));
}
public void testDuplicate()