Solr是一个开源的搜索平台,基于Apache Lucene库构建,主要用于提供全文搜索的功能。它被设计为一个高度可靠、可扩展的搜索应用服务器。以下是Solr的一些主要使用场景:
-
全文搜索:Solr最核心的功能是提供全文搜索,它可以对大量文档进行索引,并支持快速、复杂的搜索查询。这对于需要在大量数据中快速找到特定信息的网站或应用程序非常有用。
-
电子商务搜索:在线商店可以使用Solr来提供产品搜索功能,包括过滤、排序、推荐等。Solr可以提高搜索的相关性和性能,从而提升用户体验和销售额。
Solr索引采用倒排索引。倒排索引,也称为反向索引,是一种数据结构,用于存储一个单词在文档中出现的位置。这种结构使得搜索操作能够迅速找到包含特定单词的所有文档。
在Solr中,倒排索引的工作原理可以概括如下:
-
索引创建:当文档被添加到Solr中时,Solr首先对文档进行解析,提取出索引字段中的文本内容。然后,Solr使用分词器(Tokenizer)将文本分解成一系列的词汇单元(Terms),并对这些词汇进行标准化处理(如小写化、同义词扩展等)。
-
词汇映射:处理后的词汇会被映射到一个内部的唯一标识符(Term ID)。同时,Solr会记录每个词汇出现的所有文档列表。
-
倒排列表:Solr构建了一个倒排列表,其中每个唯一的词汇都是一个索引项,指向包含该词汇的所有文档的列表。这个列表通常被称为文档ID的集合。
-
查询处理:当用户发起搜索请求时,Solr会解析查询语句,找到所有匹配的词汇,并使用倒排列表快速定位到这些词汇出现的文档集合。
-
结果合并:Solr会根据查询的复杂性(如使用布尔运算符、范围查询等)合并这些文档集合,然后根据相关性排序算法对结果进行排序,最后返回给用户。
Solr的Function Query(函数查询)是一种强大的查询机制,它允许用户在搜索时执行复杂的计算和操作。Function Queries可以对字段值进行实时的数学、统计或其他类型的函数计算,然后将结果用于过滤、排序或影响查询的相关性得分。
根据搜索结果中提供的信息,以下是对Solr Function Query的一些介绍:
-
使用方式:Function Queries可以通过明确的QParser使用,例如
func
或frange
。例如,q={!func}div(popularity,price)
和fq={!frange l=1000}customer_ratings
这样的查询表达式。 -
在Sort表达式中使用:Function Queries也可以在排序表达式中使用,例如
sort=div(popularity,price) desc, score desc
,这将首先根据popularity
除以price
的结果降序排序,然后根据得分进行降序排序。 -
函数查询的类型:Solr支持多种内置函数,包括数学函数(如加法、减法、乘法、除法)、统计函数(如平均值、最大值、最小值)、文本函数(如长度、包含)等。
-
动态计算:Function Queries可以在查询时动态计算字段值,这使得可以根据实时数据进行搜索,而不是依赖于索引时的静态值。
solr的字符串函数比较缺乏,只有strdist 字符串距离,即字符串相关性。termfreq 字符串文档出现次数。连contain 即是否包含某个字符串,length字符串长度、concat字符串拼接等几个常用的字符串操作都没有实现,使用起来很不方便。比如某个文档中有个标签字段,该标签字段存放着多个标签以逗号隔开的字符串,这时如果想查满足条件的商品 同时带动漫标签的商品排序居前,发现没法满足需求。这时需要实现contain的自定义函数。下面以contain为例
-
编写自定义函数类:
- 创建一个新的Java类,该类实现
org.apache.lucene.queries.function.ValueSource
接口。 - 在类中实现
getValue(int doc)
方法,该方法定义了如何为每个文档计算函数值。 - 如果需要,还可以实现其他方法,如
getDefaultValue()
、createWeight(IndexSearcher searcher)
等。 - 创建一个新的Java类,该类实现
org.apache.solr.search.ValueSourceParser
接口。
- 创建一个新的Java类,该类实现
-
编译并打包:
- 将编写的自定义函数类编译成
.class
文件。 - 将
.class
文件打包到一个JAR文件中。
- 将编写的自定义函数类编译成
-
在
solrconfig.xml
中注册函数:- 在
solrconfig.xml
文件的<config>
标签内,添加一个<queryResponseWriter type="velocity" />
配置,以便能够使用Velocity模板。 - 在
<config>
标签内,添加<lib dir="lib" regex=".*\.jar"/>
来包含你的自定义函数JAR文件。 - 使用
<valueSourceParser name="
contain" class="your.package.MyCustomFunction"/>
来注册你的自定义函数,其中myfunc
是你在查询中使用的名称,your.package.MyCustomFunction
是你的自定义函数类的全限定名。
- 在
-
在查询中使用自定义函数:
- 在Solr查询中,你可以通过
func
QParser来使用自定义函数,例如:q={!func}
contain(field,'
动漫')
。 - 你也可以在排序或过滤中使用自定义函数,例如:
sort=
contain(field,'
动漫') asc
或fq={!frange l=0}
contain(field,'
动漫')
。
- 在Solr查询中,你可以通过
public FunctionValues getValues(Map arg0, AtomicReaderContext arg1) throws IOException {final FunctionValues v1 = field.getValues(arg0, arg1);final FunctionValues v2 = val.getValues(arg0, arg1);return new IntDocValues(this) {@Overridepublic int intVal(int arg0) {if(null==v1.strVal(arg0)) return 0;if(null==v2.strVal(arg0)) return 0;if( v1.strVal(arg0).contains(v2.strVal(arg0))) return 1;else return 0;}};}
重启后测试效果可以了