热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

理解和学习Solr的score机制

 参考:http:www.cnblogs.comrcfengp4067896.htmlhttp:www.cnblogs.comforfuture1978archive201003
 参考:http://www.cnblogs.com/rcfeng/p/4067896.htmlhttp://www.cnblogs.com/forfuture1978/archive/2010/03/07/1680007.html 在solr的document文档定义中(schema.xml),需要对每个字段进行定义indexed, stored,其中表示的含义为:  
字段名称 字段含义  
indexed 如果该字段是要做查询的,需要将其设置为indexed,进行索引,以便能够根据该字段进行查询。但是与具体分词手段无关,如果涉及到如果分词,需要使用type属性  
stored 在solr查询结果中能够正常返回,如果一个字段stored=false,则查询结果不会包括该字段。  
  而只有indexed的字段可以用于查询,虽然solr中有sort字段可以进行排序,这一般用于精确匹配的查询,例如按照分类/品牌进行搜索得到结果。如果用户采用关键词的方式进行模糊匹配,此时使用sort根据某个字段进行排序会显得不合时宜,无法帮助用户搜索到他想要的结果(更多是被sort所控制,这就好比百度的竞价排名系统)。 根据查询打分的相关文档可以看出,Solr中采用了最基本的向量空间模型: 

 
 其中存在的索引文件.tvx, tvd, tvf存储了term vector相关信息,我们学习如何使用term vector来反映相似性程度。在向量空间模型中,夹角越小,说明相似程度越大,可以用cos余弦函数定理来计算。
 

 
 相似值计算公式:t=term, d=document, q=query, f=field 
  • tf(t in d ) 表示该term 在 这个文档里出现的频率(即出现了几次)。
  •  idf(t) 表示 出现该term的文档个数。
  •  t.getBoost() 查询语句中每个词的权重,可以在查询中设定某个词更加重要。

 

  • norm(t,d) 标准化因子d.getBoost() • lengthNorm(f) • f.getBoost() ,它包括三个参数:
    • Document boost:此值越大,说明此文档越重要。
    • Field boost:此域越大,说明此域越重要。
    • lengthNorm(field) = (1.0 / Math.sqrt(numTerms)):一个域中包含的Term总数越多,也即文档越长,此值越小,文档越短,此值越大。
  • coord(q,d):一次搜索可能包含多个搜索词,而一篇文档中也可能包含多个搜索词,此项表示,当一篇文档中包含的搜索词越多,则此文档则打分越高 ,numTermsInDocumentFromQuery / numTermsInQuery 
  • queryNorm(q):计算每个查询条目的方差和,此值并不影响排序,而仅仅使得不同的query之间的分数可以比较。
 我们当前环境的/select相关配置:  



edismax
explicit
json
true
text

map(psfixstock,0,0,0,100)



1000
50






explicit
json
true
text


 
 可以看出当前使用了edismax方式,默认查询字段df为text,boost function已经被设置,但存在较大问题:搜索的排序严重与货物的库存数量相关,这肯定会导致用户无法查询出其想要的最精确的结果(即便是无库存,用户也可能希望能够返回正确的商品,而不是有库存的不相关商品)。Solr查询中的常用参数列表:  
参数 含义  
df default fields,默认查询字段  
wt writer type,指定查询输出结构格式,默认xml  
defType 设置查询解析器名称  
bf boost function,可接受多个函数查询,用空格隔开  
qf query fields,指定索引中查询字段,如果没有指定,默认使用df  
q 查询字符串,必输项  
q.op 默认查询连接符,AND OR  
sort 排序,sort=+,...  
start 分页定义结果起始记录数,默认为0  
rows 分页定义结果每页返回记录数,默认为10  
fq filter query,可充分利用filter query cache,提高检索性能。在q查询符合结果中同时是fq查询符合的  
fl field list,指定返回结果字段,以空格或逗号分隔  
timeAllowed 设置查询超时时间  
bq boost query,指定一个单词或短语提升查询权重  
mm Minimum Should Match,指定查询中必须匹配的最小规则数,如果没有在查询中或在solrconfig.xml文件中指定mm参数值,q.op参数的有效性将会受到影响。如果q.op是AND,则mm=100%,如果q.op是OR,则mm=1(100%表示全部匹配,1表示只要有一个匹配即可)。如果用户想修改这些行为,可以在solrconfig.xml文件中定义mm参数  
  Solr 支持多种查询解析,给搜索引擎开发人员提供灵活的查询解析。Solr 中主要包含这几个查询解析器:标准查询解析器、DisMax 查询解析器,扩展 DisMax 查询解析器(eDisMax)。  在solr查询时,使用debugQuery可以打印出其打分的详细信息以便我们能够正确的分析:  
"1046888": "
26.279617 = sum of:
0.9810601 = sum of:
0.1401725 = weight(text:女士 in 431) [DefaultSimilarity], result of:
0.1401725 = score(doc=431,freq=2.0), product of:
0.3656968 = queryWeight, product of:
1.4455243 = idf(docFreq=37139, maxDocs=57987)
0.25298557 = queryNorm
0.3833025 = fieldWeight in 431, product of:
1.4142135 = tf(freq=2.0), with freq of:
2.0 = termFreq=2.0
1.4455243 = idf(docFreq=37139, maxDocs=57987)
0.1875 = fieldNorm(doc=431)
0.8408876 = weight(text:手提包 in 431) [DefaultSimilarity], result of:
0.8408876 = score(doc=431,freq=2.0), product of:
0.89569205 = queryWeight, product of:
3.5404868 = idf(docFreq=4570, maxDocs=57987)
0.25298557 = queryNorm
0.9388133 = fieldWeight in 431, product of:
1.4142135 = tf(freq=2.0), with freq of:
2.0 = termFreq=2.0
3.5404868 = idf(docFreq=4570, maxDocs=57987)
0.1875 = fieldNorm(doc=431)
25.298557 = FunctionQuery(map(int(psfixstock),0.0,0.0,const(0))), product of:
100.0 = map(int(psfixstock)=1,min=0.0,max=0.0,target=const(0))
1.0 = boost
0.25298557 = queryNorm
",
  
 
女士手提包,搜索词拆分成两个词元:“女士” “手提包”,q.op默认为OR(通过设置mm的值可以影响该属性),  idf为出现的频率,单独搜索“女士”总条目数37139,单独搜索“手提包”总条目数4570,出现频次越多就越不重要,idf的计算公式:  
idf(t) = 1 + log (numDocs / (docFreq +1))
  
  termFreq=2.0,tf的计算公式,2的1/2次方,得出1.414:  
tf(t in d) = numTermOccurrencesInDocument 1/2
 
  fieldNorm取决于匹配的文档field总数,大概在29个左右(由于查询中并没有设置boost),计算公式: 
lengthNorm(field) = (1.0 / Math.sqrt(numTerms))
 
  queryNorm,用来计算每个查询条目的方差和,使得不同的query之间的分数可以进行比较: 写道queryNorm(q) = 1 / (sumOfSquaredWeights )
sumOfSquaredWeights = q.getBoost()2 • ∑ ( idf(t) • t.getBoost() )2
 
 Solr Copy Field对打分的影响  如果使用了solr中的copyfield,会对打分造成什么影响?copyfield,solr允许将不同的字段copy到一个字段中,搜索只需要搜索拷贝字段即可,当然这样会造成内容中包含非常多的搜索词。 根据在StackOverflow上的回答,如果要设置各自字段的boost,就不能使用统一的copyfield,或者将copyfield进行分组:  http://stackoverflow.com/questions/13920776/when-you-perform-a-copyfield-in-solr-does-the-field-boost-go-with-it 当前我们设置的默认df(default field)为text,整个字段,当前我们可以通过更改qf的方式来做自定义boost, 
SearchText, SearchText2^3, SearchText3^10, SearchText4^100
 
 另一种说法,在solr中支持的多值域(multiValued)其实也就是copyfield,同一个field对应多个value。当一个文档中出现同名的多值域时,倒排索引和项向量都会在逻辑上将这些词的词汇单元附加进去。当对多值域进行存储的时候,它们在文档中的存储顺序是分离的,当在搜索期间对文档进行检索时,会发现多个field实例,最后该field的boost如何计算?使用每一个值域的boost相乘。 使用Query Field  我们设置query field,将下面的三个条件作为筛选条件,并设置其boost权重:  
      brand_name^0.9 category_name^0.8 product_name^2.0
 
  此时我们查询 “胸饰”,从打开debugQuery,可以看到其中的详细评分:  
"debug": { "rawquerystring": "胸饰", "querystring": "胸饰", "parsedquery": "(+DisjunctionMaxQuery((brand_name:胸饰^0.9 | category_name:胸饰^0.8 | product_name:胸饰^2.0)) FunctionQuery(map(int(psfixstock),0.0,0.0,const(0),const(100))))/no_coord", "parsedquery_toString": "+(brand_name:胸饰^0.9 | category_name:胸饰^0.8 | product_name:胸饰^2.0) map(int(psfixstock),0.0,0.0,const(0),const(100))",
 
  我们可以定义多个 requestHandler,用来专门处理多种类型,例如模糊查询,根据商品id定位商品,后端的内部查询,将它们分开这样就可以完成不同的查询了。   
  • 大小: 42.8 KB
  • 大小: 2.7 KB
  • 查看图片附件

推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一些好用的搜索引擎的替代品,包括网盘搜索工具、百度网盘搜索引擎等。同时还介绍了一些笑话大全、GIF笑话图片、动态图等资源的搜索引擎。此外,还推荐了一些迅雷快传搜索和360云盘资源搜索的网盘搜索引擎。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
author-avatar
谭小牙笑不漏齿
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有