solr functionquery函数查询自定义函数实现

Solr是一个开源的搜索平台,基于Apache Lucene库构建,主要用于提供全文搜索的功能。它被设计为一个高度可靠、可扩展的搜索应用服务器。以下是Solr的一些主要使用场景:

  1. 全文搜索:Solr最核心的功能是提供全文搜索,它可以对大量文档进行索引,并支持快速、复杂的搜索查询。这对于需要在大量数据中快速找到特定信息的网站或应用程序非常有用。

  2. 电子商务搜索:在线商店可以使用Solr来提供产品搜索功能,包括过滤、排序、推荐等。Solr可以提高搜索的相关性和性能,从而提升用户体验和销售额。

Solr索引采用倒排索引。倒排索引,也称为反向索引,是一种数据结构,用于存储一个单词在文档中出现的位置。这种结构使得搜索操作能够迅速找到包含特定单词的所有文档。

在Solr中,倒排索引的工作原理可以概括如下:

  1. 索引创建:当文档被添加到Solr中时,Solr首先对文档进行解析,提取出索引字段中的文本内容。然后,Solr使用分词器(Tokenizer)将文本分解成一系列的词汇单元(Terms),并对这些词汇进行标准化处理(如小写化、同义词扩展等)。

  2. 词汇映射:处理后的词汇会被映射到一个内部的唯一标识符(Term ID)。同时,Solr会记录每个词汇出现的所有文档列表。

  3. 倒排列表:Solr构建了一个倒排列表,其中每个唯一的词汇都是一个索引项,指向包含该词汇的所有文档的列表。这个列表通常被称为文档ID的集合。

  4. 查询处理:当用户发起搜索请求时,Solr会解析查询语句,找到所有匹配的词汇,并使用倒排列表快速定位到这些词汇出现的文档集合。

  5. 结果合并:Solr会根据查询的复杂性(如使用布尔运算符、范围查询等)合并这些文档集合,然后根据相关性排序算法对结果进行排序,最后返回给用户。

Solr的Function Query(函数查询)是一种强大的查询机制,它允许用户在搜索时执行复杂的计算和操作。Function Queries可以对字段值进行实时的数学、统计或其他类型的函数计算,然后将结果用于过滤、排序或影响查询的相关性得分。

根据搜索结果中提供的信息,以下是对Solr Function Query的一些介绍:

  1. 使用方式 :Function Queries可以通过明确的QParser使用,例如funcfrange。例如,q={!func}div(popularity,price)fq={!frange l=1000}customer_ratings这样的查询表达式。

  2. 在Sort表达式中使用 :Function Queries也可以在排序表达式中使用,例如sort=div(popularity,price) desc, score desc,这将首先根据popularity除以price的结果降序排序,然后根据得分进行降序排序。

  3. 函数查询的类型:Solr支持多种内置函数,包括数学函数(如加法、减法、乘法、除法)、统计函数(如平均值、最大值、最小值)、文本函数(如长度、包含)等。

  4. 动态计算:Function Queries可以在查询时动态计算字段值,这使得可以根据实时数据进行搜索,而不是依赖于索引时的静态值。

solr的字符串函数比较缺乏,只有strdist 字符串距离,即字符串相关性。termfreq 字符串文档出现次数。连contain 即是否包含某个字符串,length字符串长度、concat字符串拼接等几个常用的字符串操作都没有实现,使用起来很不方便。比如某个文档中有个标签字段,该标签字段存放着多个标签以逗号隔开的字符串,这时如果想查满足条件的商品 同时带动漫标签的商品排序居前,发现没法满足需求。这时需要实现contain的自定义函数。下面以contain为例

  1. 编写自定义函数类

    • 创建一个新的Java类,该类实现org.apache.lucene.queries.function.ValueSource接口。
    • 在类中实现getValue(int doc)方法,该方法定义了如何为每个文档计算函数值。
    • 如果需要,还可以实现其他方法,如getDefaultValue()createWeight(IndexSearcher searcher)等。
    • 创建一个新的Java类,该类实现org.apache.solr.search.ValueSourceParser接口。
  2. 编译并打包

    • 将编写的自定义函数类编译成.class文件。
    • .class文件打包到一个JAR文件中。
  3. 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是你的自定义函数类的全限定名。
  4. 在查询中使用自定义函数

    • 在Solr查询中,你可以通过func QParser来使用自定义函数,例如:q={!func}contain(field,'动漫')
    • 你也可以在排序或过滤中使用自定义函数,例如:sort=contain(field,'动漫') ascfq={!frange l=0}contain(field,'动漫')
java 复制代码
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) {
			@Override
			public 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;
			}
			
		};
	}

重启后测试效果可以了

相关推荐
cyh男3 天前
lucene中AutomatonQuery类的作用
lucene
cyh男3 天前
lucene中的PointRangeQuery和PointInSetQuery有什么区别
lucene
cyh男3 天前
为什么ES中不推荐使用wildcard查询
elasticsearch·lucene
渣渣盟4 天前
中文分词技术全解析
搜索引擎·全文检索·lucene
cyh男17 天前
lucene 8.7.0 版本中的倒排索引、数字、DocValues三种类型的查询性能对比
lucene
cyh男18 天前
Lucene 8.7.0 版本中dvd、dvm文件详解
lucene
是犹橐籥19 天前
头歌Educoder答案 Lucene - 全文检索入门
搜索引擎·全文检索·lucene
cyh男19 天前
Lucene 8.7.0 版本中docFreq、totalTermFreq、getDocCount等方法的含义
lucene
李白你好21 天前
Solr任意文件读取-快速利用工具
solr
cyh男21 天前
Lucene 8.7.0 版本中doc、tim、tip、tmd文件详解
lucene