Solr高亮及搜索逻辑探寻

2024-09-02 22:08
文章标签 搜索 逻辑 探寻 高亮 solr

本文主要是介绍Solr高亮及搜索逻辑探寻,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Solr高亮及搜索逻辑探寻


原文:http://leoluo.top/2017/11/21/Solr%E6%95%B0%E5%AD%97%E9%AB%98%E4%BA%AE%E5%BC%82%E5%B8%B8/
Blog:Why So Serious
Github: LeoLuo22
CSDN: 我的CSDN


0x00 前言

马上就要发版本了,这次版本要新上对产品和功能的搜索。

但是,却有一个问题,高亮问题。

比如:

搜索 111

返回:中银易贷【1243215321534】【 12345674687】

可以看到,整个数字串都被高亮了。同样,搜索 证,搜索结果中的证券期货,证券会被高亮。明显不是我们想要的效果。

分析

Solr对域(field)和域类型(fieldType)以及分词策略都定义在managed-schema里面。

先看一下之前其他人定义的manage-schema的关键部分。

<fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100"><analyzer>        <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/bmsvr/solrdata/dic" /><filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/><filter class="solr.LowerCaseFilterFactory" /><filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="50"  /></analyzer>     
</fieldType><field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false"/>
<field name="indexTypeCode" type="string" indexed="false" stored="true"/>
<field name="indexTypeName" type="textComplex" indexed="true" stored="true"/>
<field name="proCode" type="textComplex" indexed="true" stored="true" multiValued="false"/>
<field name="proName" type="textComplex" indexed="true" stored="true"/>
<field name="proUrl" type="string" indexed="false" stored="true"/><field name="funCode" type="string" indexed="false" stored="true"/>
<field name="funName" type="textComplex" indexed="true" stored="true"/>
<field name="funUrl" type="string" indexed="false" stored="true"/><field name="dataType" type="string" indexed="true" stored="true"/><field name="product" type="string" indexed="true" stored="true"/><field name="suggest" type="textComplex"  indexed="true"  stored="false" multiValued="true"/><field name="text" type="textComplex" stored="false" indexed="true" multiValued="true"/><field name="_version_" type="long" indexed="true" stored="true"/><uniqueKey>id</uniqueKey><defaultSearchField>text</defaultSearchField><copyField source ="proCode" dest="text"/>                              
<copyField source ="proName" dest="text"/>
<copyField source ="funName" dest="text"/>
<copyField source ="indexTypeName" dest="text"/><copyField source ="proCode" dest="suggest"/>                              
<copyField source ="proName" dest="suggest"/>
<copyField source ="funName" dest="suggest"/>
<copyField source ="indexTypeName" dest="suggest"/>

默认的搜索域是text,text的类型是textComplex,textComplex的分词策略如下:

<fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100">
<analyzer>        
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/bmsvr/solrdata/dic" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="50"  />
</analyzer>     
</fieldType>   

怀疑是否是分词策略的原因。

可以看到,分词策略首先是匹配停用词(stopword),然后匹配同义词,然后转换为小写,最后使用edgengram分词。

凭证的分词结果是凭,凭证。
111的分词结果是 1, 11, 111,type是word

图1

solrconfig.xml有关高亮的配置如下:

   <!--高亮--><str name="hl">on</str><str name="hl.fl">proCode proName funName</str><str name="hl.encoder">html</str><str name="hl.simple.pre"><b></str><str name="hl.simple.post"></b></str><str name="f.proCode.hl.fragsize">0</str><str name="f.proCode.hl.alternateField">proCode</str><str name="f.proName.hl.fragsize">0</str><str name="f.proName.hl.alternateField">proName</str><str name="f.funName.hl.fragsize">0</str><str name="f.funName.hl.alternateField">funName</str></lst>   

查阅了Solr的官方文档,只说明了高亮的配置,并没有介绍高亮的逻辑。

之前还有一个问题,产品索引库了存在proName为凭证的索引内容,但是搜索 证券,凭证就是搜不出来。

我查看了一下他俩的分词结果:

凭证的分词是凭,凭证

证券期货的分词是证,证券。

那么,会不会是搜索结果与搜索内容和搜索结果的分词结果相关?

为了测试,我修改了分词

默认的proCode和proName两个域都是text类型。但是后来我把proCode的分词策略改了。以搜索 111q 为例。

高亮返回:

"20171110220007683664-874947726": {"proCode": ["xian-<em>111</em>5"],"proName": ["xian-<em>1115</em>"]
},   

可以看到proCode只有111加了高亮,而proName整个1115都加了高亮。

xian-1115的proCode的分词结果为:

x
xi
i
3
ia
a
an
n
-1
1
11
1
11
1
15
5

而text的分词结果为:

x
xi
xia
xian
1
11
111
1115

see?proCode高亮了111, proName高亮了1115。貌似是根据结果域分词最长的句子来匹配的。

为了验证,我在数据库添加了一条数据,proCode和proName都是100011ab

搜索100011

"201711061433224775011720779125": {"proCode": ["<em>100011</em>ab"],"proName": ["<em>100011ab</em>"]
},   

proCode分词结果:

1
10
0
00
0
00
0
01
1
11
1
1a
a
ab
b

proName的分词结果是:

1
10
100
1000
10001
100011
100011a
100011ab

高亮的应该是结果域的分词结果能和搜索内容匹配的最多的。

而且,还与搜索内容的分词结果相关。

比如,搜索100011ab,默认是text分词。

现象:proCode只高亮了100011

搜索proCode:100011ab

proCode高亮了100011ab

贪心匹配。

所以我对高亮策略的猜想:搜索内容的分词结果与结果的分词结果贪心匹配。

Solution

第一个想法是 既然是对结果分词的贪心匹配

那 如果把结果域分得足够细呢?

<fieldType name="proCodeIndex" class="solr.TextField"><analyzer><tokenizer class="solr.NGramTokenizerFactory" minGramSize="1" maxGramSize="1" /><filter class="solr.LowerCaseFilterFactory" /><filter class="solr.ClassicFilterFactory" /></analyzer>     
</fieldType>   

我把结果域使用了上述划分,划分效果如图2.

image

可以看到,直接是拆成了单字的形式。同样的,我对搜索域的分词策略也进行了修改。

fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100"><analyzer>        <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/bmsvr/solrdata/dic" /><filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/><filter class="solr.LowerCaseFilterFactory" /><!-- <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="50"  /> --><filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="5"/><filter class="solr.RemoveDuplicatesTokenFilterFactory" /></analyzer>     
</fieldType>   

分词效果如图3

image

最后,将结果域的copyField设置为了text

<copyField source ="proCode" dest="text"/>
<copyField source ="proName" dest="text"/>
<copyField source ="funName" dest="text"/>
<copyField source ="indexTypeName" dest="text"/><copyField source ="proCode" dest="suggest"/>                              
<copyField source ="proName" dest="suggest"/>
<copyField source ="funName" dest="suggest"/>
<copyField source ="indexTypeName" dest="suggest"/>

现在的高亮效果如下。

image
image
可以看到,只会对与搜索内容匹配的高亮,而不是高亮一大块。但目前还有的小问题就是不会高亮全角的字符。

这篇关于Solr高亮及搜索逻辑探寻的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131203

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

hdu4277搜索

给你n个有长度的线段,问如果用上所有的线段来拼1个三角形,最多能拼出多少种不同的? import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

Solr 使用Facet分组过程中与分词的矛盾解决办法

对于一般查询而言  ,  分词和存储都是必要的  .  比如  CPU  类型  ”Intel  酷睿  2  双核  P7570”,  拆分成  ”Intel”,”  酷睿  ”,”P7570”  这样一些关键字并分别索引  ,  可能提供更好的搜索体验  .  但是如果将  CPU  作为 Facet  字段  ,  最好不进行分词  .  这样就造成了矛盾  ,  解决方法

Solr部署如何启动

Solr部署如何启动 Posted on 一月 10, 2013 in:  Solr入门 | 评论关闭 我刚接触solr,我要怎么启动,这是群里的朋友问得比较多的问题, solr最新版本下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/ 1、准备环境 建立一个solr目录,把solr压缩包example目录下的内容复制

浙大数据结构:04-树7 二叉搜索树的操作集

这道题答案都在PPT上,所以先学会再写的话并不难。 1、BinTree Insert( BinTree BST, ElementType X ) 递归实现,小就进左子树,大就进右子树。 为空就新建结点插入。 BinTree Insert( BinTree BST, ElementType X ){if(!BST){BST=(BinTree)malloc(sizeof(struct TNo

逻辑表达式,最小项

目录 得到此图的逻辑电路 1.画出它的真值表 2.根据真值表写出逻辑式 3.画逻辑图 逻辑函数的表示 逻辑表达式 最小项 定义 基本性质 最小项编号 最小项表达式   得到此图的逻辑电路 1.画出它的真值表 这是同或的逻辑式。 2.根据真值表写出逻辑式   3.画逻辑图   有两种画法,1是根据运算优先级非>与>或得到,第二种是采

UMI复现代码运行逻辑全流程(一)——eval_real.py(尚在更新)

一、文件夹功能解析 全文件夹如下 其中,核心文件作用为: diffusion_policy:扩散策略核心文件夹,包含了众多模型及基础库 example:标定及配置文件 scripts/scripts_real:测试脚本文件,区别在于前者倾向于单体运行,后者为整体运行 scripts_slam_pipeline:orb_slam3运行全部文件 umi:核心交互文件夹,作用在于构建真