SolrJ源码:基本文档和域对象

SolrInputDocument相当于Document,而SolrInputFiled就是域。SolrInputFiled也存了域名称

默认boost都是1.0, boost用于标准化因子:docBoot*fieldBoot*? 即文档或域的重要程度

一、SolrInputDocument对象:输入文档对象

class SolrInputDocument implements Map<String,SolrInputField>, Iterable<SolrInputField>, Serializable

1、主要用于存储doc中的各字段的是 private final Map<String,SolrInputField> _fields = new LinkedHashMap<String,SolrInputField>();

doc的boost是_documentBoost,可以设置。

 

2、addField(String name, Object value, float boost ):

先SolrInputField field = _fields.get( name ); 如果field是空或field.value==null,则setField()

如果该域有值,就把新的值放到原值后面,即field.addValue(value,boost)

3、setField(String name, Object value, float boost ):

创建SolrInputField对象field = new SolrInputField(name); 然后field.addValue(value,boost)。再把field放到_fields中即_fields.put(name,field);

由于SolrInputFiled在addValue时会保存原值,在原值基础上添加新值,而getFieldValue时又取得的是集合第一个值即最早的值,所以doc.addField()有可能对已经存在的域造成困惑,所以用setField会好些吧。

4、putAll(Map<String,? extends SolrInputField> t):

直接_fields.putAll(t)

5、Object getFieldValue(String name):得到某个域中的值,由于域中新加的值会追加到原值后面,所以域中值有可能会是Collection,所以取值时一般取第一个
_fields.get(name).getFirstValue()

6、getFieldValues(String name)就可以得到该域中的值集合

7、拥有Map的所有方法,其实就是调用_fields的各种Map方法。比如迭代时取出的是Collection<SolrInputField>

二、SolrInputField:输入文档的域

class SolrInputField implements Iterable<Object>, Serializable

1、属性是name,value,boost=1.0f

value值如果就一个值时就Object,如果多于1个值时就是一个Collection,而有多值的Field的boost*=newBoost, 是所有值的boost积。

solrj说这种设计方案只是为了扩展,lucene现在并不支持这样的多值。solr4.x支持一个域多值的情况(当然是对某个doc)

// The lucene API and solr XML field specification make it possible to set boosts on multi-value fields even though lucene indexing does not support this. To keep behavior consistent with what happens in the lucene index, we accumulate the product of all boosts specified for this field.

2、setValue(Object v,float b): set的话是给value赋值,add的话是在原值集合上加入。

当v instanceof Object[]时,则创建Collection<Object> c = new ArrayList<Object>( ((Object[])v).length )//ArrayList创建时的length是初始化大小,后面可以再增加;并将v中对象都add到c中,然后value=c。 非Object[]时直接value=v

3、addValue(Object v,float b): 在原值集合上再添新值

a、value==null:

如果v instance Collection的话,则Collection<Object> c = new ArrayList<Object>( 3 );把v中的值都添加到c中。然后setValue(c,b),这里为什么不直接使用v而要创建新的c?是怕外部可以修改v的值,进而修改了value。但这也只保证了value中值的个数,没法保证value中值集合非基本类型的值的变化。

如果v不是集合,则setValue(v,b)。如果v是数组也没事,因为在setValue已经对数组进行变成集合的处理(真是蛋疼,干嘛单单把数组移到setValue中了)

b、value不空时:boost*=b

声明Collection<Object> vals = null

如果value instanceof Collection时则vals=(Collection<Object>)value

如果value是普通对象(不可能是数组,因为setValue是多值的话都会转成集合),则vals=new ArrayList<Object>( 3 ); vals.add(value);value=vals;把单值value变成集合value。 这样vals==value 为true了

然后将v添加到vals中,即如果v是集合、数组、迭代时都将其所有元素都添加到vals中,也即values中

4、Object getFirstValue():

如果value非集合则返回value,如果value是集合,则返回集合的第一个元素,value.iterator().next()。(这样新值加进去后,SolrInputDocument.getFieldValue()得到的居然是最早的那个,而不是最新的那个,这个弄哪样?)


5、迭代方法返回值集合中的各个元素

6、deepCopy 完全拷贝,如果value是集合类的话,则创建该集合类,再集合类addAll

三、SolrDocument:查询结果文档对象

SolrDocument implements Map<String,Object>, Iterable<Map.Entry<String, Object>>, Serializable

1、Map<String,Object> _fields = new LinkedHashMap<String,Object>();//存储各域值

2、setField(String name, Object value):

当value是数组或Iterable时新建集合并把value的元素都放到集合中,再_fields.put(name, 集合)。

3、addField(String name, Object v)

和SolrInputField的addValue方法类似,原value=_fields.get(name)。value是空的话,v是集合,则新建集合把v的元素加进来,

_fields.put(name,集合),v是普通元素,则_fields.put(name,v)。 value不空,则弄个集合把v加进来。

4、getFirstValue也是获得值集合的第一个元素

5、各种Map方法

四、SolrDocumentList:查询结果文档列表

SolrDocumentList extends ArrayList<SolrDocument>

增加的属性: maxScore, numFound, start

加这三个属性想必是从查询结果中的一部分,比如query.setRow(10),query.setStart(0)时得到的所有符合条件的文档信息,如这些文档最高分数是maxScore,文档总数numFound,还有这个SolrDocumentList对应查询结果集合中的offset

toString时返回的结果是:"{numFound="+numFound+",start="+start+ (maxScore!=null ? ",maxScore="+maxScore : "")+",docs="+super.toString()+"}";显示本列表中的元素信息以及总查询结果的一些信息。

猜你喜欢

转载自wangzejie.iteye.com/blog/2000340