您的位置:首页 > 产品设计 > UI/UE

solr multivalue的实现分析 推荐

2014-07-03 00:04 393 查看
线上业务准备使用solr做数据存放和索引的功能,其中有的字段要求会存入多个字,solr的field的
multivalue可以实现这个功能。

<dynamicField name="*_ss" type="string"  indexed="true"  stored="true" multiValued="true"/>
下面看看其实现原理:
和solr的写入document相关的两个类是SolrInputDocument 和SolrInputField,其中SolrInputDocument 是和整条document有关,SolrInputField 是和field相关(属性包含field的名称,值和boost值)。
SolrInputDocument 类中和document添加的方法主要有addField 和setField,其中setField是覆盖前面的value,addField是追加value.
看看其具体实现:

public SolrInputDocument() {
_fields = new LinkedHashMap <String,SolrInputField>(); // 通过构造方法构建一个map,value是SolrInputField
}
private final Map<String,SolrInputField> _fields;
public void addField(String name, Object value, float boost ) //addFiled的方法中,参数value是个object
SolrInputField field = _fields.get( name ); // name是指field的名称,value是指field的值,判断map中是否已经有这个field的信息
if( field == null || field.value == null ) { // 如果filed或者filed value为空,就用本类的setField(即第一次添加有效地值,类似于overwrite)
setField(name, value, boost);
}
else {
field.addValue( value, boost ); // 否则用SolrInputField的addValue方法(类似于append)
}
}
其中setField的实现如下:

public void setField(String name, Object value, float boost )
{
SolrInputField field = new SolrInputField( name );
_fields.put( name, field );
field.setValue( value, boost );  //其实是调用了SolrInputField的setValue方法
}
再来看看SolrInputField类:

public class SolrInputField implements Iterable<Object>, Serializable
{
String name;
Object value = null;
float boost = 1.0f;
public SolrInputField( String n )
{
this. name = n;
}
public void setValue(Object v, float b) {
boost = b;
if( v instanceof Object[] ) {  // Arrays will be converted to a collection.如果传入的value是个list,会转换为collection
Object[] arr = (Object[])v;
Collection<Object> c = new ArrayList<Object>( arr.length );
for( Object o : arr ) {
c.add( o );
}
value = c;
}
else {
value = v;
}
}
public void addValue(Object v, float b) { //可以看到同样会判断是否为collection
if( value == null ) {
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;
}
....

通过上面可以看出,在向field传入value的时候,是可以传入数组这种数据结构的,这样,就可以在一个field里面插入多个value
比如下面的两种方法,都可以写入同一个field多个有效值:
例1:

SolrInputDocument doc = new SolrInputDocument();
String key = "123";
doc.addField("id", key);
doc.addField("test_ss", "vv1");
doc.addField("test_ss", "vv2");
doc.addField("test_ss", "vv3");
例2:

SolrInputDocument doc = new SolrInputDocument();
String key = "123";
String[] vv = {"vv1","vv2","vv3"};
doc.addField("id", key);
doc.addField("test_ss", vv);
注意,每次实例化一个SolrInputDocument 的对象,都相当于对这一行进行重新overwrite的操作,因为solr是基于lucene的,lucene的update是通过delete+add实现的。也就是如果一个document为id:1,test_ss:aa,在后面重新实例化后,对于相同的id记录,使用addFiled("test_ss","bb")之后document变为id:1,test_ss:bb了。。(setField的覆盖和addField的追加都是对本次实例说的)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  solr multivalue