在上一篇博客中已经说了,valueSource就是获得一个doc的某些值,这个值可以是doc的某些域的值,也可以是现计算的一些函数值,这个博客里面就说一下solr中已经存在的valueSource。
valueSource的实现类有很多,在solr的源码中我看到了有:
1、ConstantNumberSource,即所有的doc都共享一个值得valueSource,这个类还有很多子类,待用到时再看吧。
2、有关距离的,用在地图计算上的valueSource,存在于lucene的spatial包里面,这个因为我没有用到,也没看。
3、有关倒排表长度、idf、tf的valueSource,
DocFreqValueSource:这个是计算一个指定的term的倒排表的长度的valueSource,在构造方法中就要传进去要查询的域和term的字符串。最后返回的FunctionValues是一个ConstIntDocValues,他里面的所有的doc都是同一个值,即要查询的term的倒排表的长度,也就是docFrequence。
IDFValueSource:这个和上面的DocFreqValueSource类似,只不过他不是计算一个term的docFre,而是计算一个term的idf值,最后返回的也是一个常数的FunctionValues.
TermFreqValueSource:这个是查询指定的term的倒排表中的所有的doc中含有这个term的次数的值得valueSource。
TFValueSource:这个和上面的TermFreqValueSource是类似的,只不过是返回最后经过tf函数计算的值,而上面是返回term frequence的真实值,没有经过函数计算。
4、DualFloatFunction,从字面上理解,这个是两元的浮点类型的函数,看了源码就知道,他是对两个valueSource,根据一定的函数,计算两个值的函数值的valueSource,是一个抽象类,他的具体实现类都实现了具体的函数,比如相加的,相除的,相乘的,这些简单的函数都是solr自己带的,在solr的ValueSourceParser的代码里面可以发现这些。
他的很多实现都是静态内部类,所以我这里就不记录了,在solr中存在的有:相除的----DivFloatFunction(在solr中的名字是div),也就是用一个值除以另一个值,相减的,在solr中的名字是ms,取模的,在solr中的名字是mod,
5、FieldCacheSource,这个就是从FieldCache中获得值得valueSource,很简单。他有很多实现类。
在solr中我们最终使用的是valueSource,但是我们在调用solr的api的时候,只能传字符串,所以需要一个解析器,这个和我们使用的queryParser的道理是一致的,在solr中解析valueSource的类叫做valueSourceParser(类比于queryParser),我们看一下这个类,就知道solr自带的有哪些valueSource了。在这个类中,有个一静态的map(类比于QParserPlugin中的数组),就是实现了valueSourceParser的名字到实例的映射。
/* standard functions */ public static MapstandardValueSourceParsers = new HashMap ();
在他的静态块里面,就会初始化很多的parser,放到数组里面,以后我们在使用FunctionQuery的时候,最终在计算得分的时候,就是根据传递过来的参数从这个map中查找具体的valueSourceParser,然后使用这个parser计算一个valueSource,用于排序。当然我们也可以自定义valueSourceParser,只要继承自这个valueSourceParser,实现他的parse(FunctionQParser)方法,最后返回一个valueSource。当然还需要在solrConfig中配置一下
这样我们就可以实现自己的valueSourceParser来实现自己需要的而solr没有提供的函数了。
另外,还有一个地方需要注意,在solr的facet的时候,有的情况会的使用valueSource(比如在facet field的时候,会优先使用valueSource),那么valueSource是怎么获得最后的值得呢?在solr的FieldType里面有这么一个方法:org.apache.solr.schema.FieldType.getValueSource(SchemaField, QParser),可以发现就是从FiledCache中获得valueSource值,也就是说在solr中通过FieldType获得valueSource就是使用了FieldCache,也就是会优先从docValue里面查找,如果查不到再从词典表里面查找。