【大数据开发运维解决方案】Solr6.2默认相似性算法检索匹配得分高于5.1版本问题分析

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 我们之前使用的solr版本是solr5.1,分词器使用的是jcseg1.9.6,后续接触了Solr6.2,分词器使用的是jcseg2.6.0,发现同一个Oracle库的同一套表数据,分别使用solr5.1和solr6.2版本的模板collection配置集做相同的字段配置并成功做索引后,做相同查询,solr6.2检索文档score远高于solr5.1,下面是我们使用的两个solr环境以及另一个单机solr测试环境的基本情况:

Solr6.2默认相似性算法检索匹配得分高于5.1版本问题分析

注意:
我们之前使用的solr版本是solr5.1,分词器使用的是jcseg1.9.6,后续接触了Solr6.2,分词器使用的是jcseg2.6.0,发现同一个Oracle库的同一套表数据,分别使用solr5.1和solr6.2版本的模板collection配置集做相同的字段配置并成功做索引后,做相同查询,solr6.2检索文档score远高于solr5.1,下面是我们使用的两个solr环境以及另一个单机solr测试环境的基本情况:

大数据环境 solr版本
CDH Solr5.1
华为云 Solr6.2
单机 开源Solr6.2

一、问题重现

现有华为云solr6.2和cdh5.1以及开源solr6.2三个环境的solr,索引的数据均从同一个oracle11.2.0.4库表用相同的逻辑取数据,collection或core名字分别为uoc-buyer1、uoc-buyer、uoc-buyer,现分别从三个环境做下面问题查询:

q=engname%3A(ADNAN+UL+HAQ)%5E5+buyeraddr%3A(PP+NO+AF1401302+ADD%5C%3ATOBA+TEK+SINGH%2CPAKISTAN)%5E2+flag%3A(0%5E2+1%5E1)
&fq=%7B!frange+l%3D1.8%7Dquery(%24q)
&fq=-accuracylel%3A1
&fq=countrycode%3APAK
&fq=flag%3A0
&sort=flag+asc%2Caccuracylel+desc%2Cscore+desc
&fl=chnname%2Cengname%2Cbuyeraddr%2Cpuppetbn%2Cflag%2Ctableflag%2Cscore%2Ccountrycode
&wt=json
&indent=true

开源及华为云solr6.2检索得分:
image.png

二、问题分析

1、问题原因是否由于分词器版本不一致导致

因为我们之前开始时使用的是solr5.1,相关代码开发和相识度分数认定的分数线也是基于solr5.1来做的,所以在后续将collection逻辑拿到6.2版本的开源和华为云solr后,发现分数差别很大。
首先怀疑是不是分词器导致的,因为两个solr6.2分词器使用的是jcseg2.6.0,而cdh的solr5.1使用的是1.9.6版本,于是通过三个solr的analyze功能分析要查询的地址:
两个使用jcseg2.6.0的solr6.2:
image.png
使用jcseg1.9.6的solr5.1:
image.png
两个结果比较了下,感觉还是1.9.6版本的英文分词结果更友好,2.6.0版本分词分的太细致了,将本应该在一起的单词也给拆分的七零八落了。
于是根据jcseg1.9.6的默认配置去修改jcseg2.6.0的分词器配置,最终修改后的jcseg-core-2.6.0.jar分词器中的配置文件jcseg.properties内容为:

# Jcseg properties file.
# @Note: 
# true | 1 | on for open the specified configuration or
# false | 0 | off to close it.
# bug report chenxin <chenxin619315@gmail.com>

# Jcseg function
#maximum match length. (5-7)
jcseg.maxlen = 5

#Whether to recognized the Chinese name.
jcseg.icnname = true

#maximum chinese word number of english chinese mixed word. 
jcseg.mixcnlen = 3

#maximum length for pair punctuation text.
jcseg.pptmaxlen = 7

#maximum length for Chinese last name andron.
jcseg.cnmaxlnadron = 1

#Whether to clear the stopwords.
jcseg.clearstopword = false

#Whether to convert the Chinese numeric to Arabic number. like '\u4E09\u4E07' to 30000.
jcseg.cnnumtoarabic = true

#Whether to convert the Chinese fraction to Arabic fraction.
#@Note: for lucene,solr,elasticsearch eg.. close it.
jcseg.cnfratoarabic = false

#Whether to keep the unrecognized word.
jcseg.keepunregword = true

#Whether to do the secondary segmentation for the complex English words
jcseg.ensecondseg = true

#min length of the secondary simple token. (better larger than 1)
jcseg.stokenminlen = 2

#minimum length of the secondary segmentation token.
jcseg.ensecminlen = 1

#Whether to do the English word segmentation
#the jcseg.ensecondseg must set to true before active this function
jcseg.enwordseg = false

#maximum match length for English extracted word
jcseg.enmaxlen = 16

#threshold for Chinese name recognize.
# better not change it before you know what you are doing.
jcseg.nsthreshold = 1000000

#The punctuation set that will be keep in an token.(Not the end of the token).
jcseg.keeppunctuations = @#%.&+

#Whether to append the pinyin of the entry.
jcseg.appendpinyin = false

#Whether to load and append the synonyms words of the entry.
jcseg.appendsyn = true


####for Tokenizer
#default delimiter for JcsegDelimiter tokenizer
#set to default or whitespace will use the default whitespace as delimiter
#or set to the char you want, like ',' or whatever
jcseg.delimiter = default

#default length for the N-gram tokenizer
jcseg.gram = 1


####about the lexicon
#absolute path of the lexicon file.
#Multiple path support from jcseg 1.9.2, use ';' to split different path.
#example: lexicon.path = /home/chenxin/lex1;/home/chenxin/lex2 (Linux)
#        : lexicon.path = D:/jcseg/lexicon/1;D:/jcseg/lexicon/2 (WinNT)
#lexicon.path=/Code/java/JavaSE/jcseg/lexicon
#lexicon.path = {jar.dir}/lexicon ({jar.dir} means the base directory of jcseg-core-{version}.jar)
#@since 1.9.9 Jcseg default to load the lexicons in the classpath
lexicon.path = {jar.dir}/lexicon

#Whether to load the modified lexicon file auto.
lexicon.autoload = true

#Poll time for auto load. (seconds)
lexicon.polltime = 30


####lexicon load
#Whether to load the part of speech of the entry.
jcseg.loadpos = true

#Whether to load the pinyin of the entry.
jcseg.loadpinyin = false

#Whether to load the synonyms words of the entry.
jcseg.loadsyn = true

#Whether to load the entity of the entry
jcseg.loadentity = true

修改后的jcseg分词器分词效果如下:
image.png
已经与jcseg1.9.6分词效果基本一致了,这时候两个solr6.2.0再重做索引,再次执行之前的查询,发现检索得分还是100多分。

2、问题原因是否由于solr6和5默认相似性算法不一致导致

根据上面实验,于是这里怀疑不只是因为分词器分词差异导致的问题,更大的问题应该在于solr5和solr6的相似度得分算法不一样了,为了排除分词器带来的影响,于是将solr6.2使用的分词器也替换成solr5.1使用那一套分词器,再次索引同样的数据,做同样的查询发现得分还是很高,那就说明相似得分差异过大的主要原因是由于solr两个版本的算法不一致导致的了。
经过网上查找资料发现了solr5和solr6的默认相似度算法的确是变了:

默认的相似性改变

当 Schema 没有明确地定义全局 \<similarity/> 时,Solr 的默认行为将依赖于 solrconfig. xml 中指定的
luceneMatchVersion。当 luceneMatchVersion < 6.0 时,将使用
ClassicSimilarityFactory 的实例,否则将使用 SchemaSimilarityFactory
的实例。最值得注意的是,这种改变意味着用户可以利用每个字段类型的相似性声明,并且需要明确声明 SchemaSimilarityFactory
的全局用法。 无论是明确声明还是作为隐式全局默认值使用,当字段类型不声明明确\<similarity/>
时,SchemaSimilarityFactory 的隐式行为也被更改为依赖于 luceneMatchVersion。当
luceneMatchVersion < 6.0 时,将使用 ClassicSimilarity 的实例,否则将使用
BM25Similarity 的实例。可以在 SchemaSimilarityFactory 声明中指定
defaultSimFromFieldType init 选项来更改此行为。请查看
SchemaSimilarityFactoryjavadocs 了解更多详情

于是修改solr6.2的manage-schema,新增similarity显示指定:

<similarity class="solr.ClassicSimilarityFactory"/>

而且由于当前环境索引速度较慢,同时修改solrconfig.xml的索引并行度:

<maxIndexingThreads>32</maxIndexingThreads>

重启solr,重做索引,发现现在索引速度比原来快了一个小时,再次做同样的查询,检索得分已经同solr5.1相似了:
image.png

相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
相关文章
|
1月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
60 4
|
1月前
|
存储 分布式计算 算法
大数据-106 Spark Graph X 计算学习 案例:1图的基本计算、2连通图算法、3寻找相同的用户
大数据-106 Spark Graph X 计算学习 案例:1图的基本计算、2连通图算法、3寻找相同的用户
60 0
|
3月前
|
SQL 分布式计算 DataWorks
DataWorks产品使用合集之如何开发ODPS Spark任务
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
6天前
|
机器学习/深度学习 人工智能 监控
智慧交通AI算法解决方案
智慧交通AI算法方案针对交通拥堵、违法取证难等问题,通过AI技术实现交通管理的智能化。平台层整合多种AI能力,提供实时监控、违法识别等功能;展现层与应用层则通过一张图、路口态势研判等工具,提升交通管理效率。方案优势包括先进的算法、系统集成性和数据融合性,应用场景涵盖车辆检测、道路环境检测和道路行人检测等。
|
13天前
|
缓存 算法 大数据
大数据查询优化算法
【10月更文挑战第26天】
35 1
|
20天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
21 3
|
20天前
|
机器学习/深度学习 数据采集 算法
大数据中缺失值处理使用算法处理
【10月更文挑战第21天】
33 3
|
19天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
2月前
|
算法 计算机视觉
Mat未初始化引起拼接算法结果,release版本和debug版本不一致
在OpenCV中由于Mat对象未初始化导致的拼接算法在release版本和debug版本中结果不一致的问题,并提供了通过显式初始化Mat对象为零来解决这一问题的修改方法。
|
2月前
|
SQL 分布式计算 大数据
代码编码原则和规范大数据开发
此文档详细规定了SQL代码的编写规范,包括代码的清晰度,执行效率,以及注释的必要性。它强调所有SQL关键字需统一使用大写或小写,并禁止使用select *操作。此外,还规定了代码头部的信息模板,字段排列方式,INSERT, SELECT子句的格式,运算符的使用,CASE语句编写规则,查询嵌套规范,表别名定义,以及SQL注释的添加方法。这些规则有助于提升代码的可读性和可维护性。
46 0