转载请标明出处:http://blog.csdn.net/hu948162999/article/details/47727159

本文主要介绍了在短语、句子、多词查询中。solr在控制查询命中数量、之后再对结果集进行排序

在solr中
默认是or 查询。也就是说:假设搜索q 中 分出来的词越多。所匹配的数量也就越多。

如:搜索短语  “中国联想笔记本” ,分词结果:中国 、联想 、 笔记本。

覆盖结果集:仅仅要文档中包括这3个随意词,都给返回。

排序结果:依照solr的打分公式。默认匹配相关度最高的文档放在第一位。。简单的说。就是文档中。同一时候含有 中国
、联想 、 笔记本 分值最高。这样的需求一般能够满足部分的企业级搜索。

可是:假设须要自己定义排序的话,问题就逐渐暴露了。

通过requestHandler queryParser edismax 中的 df qf,通过字段的权重配置和 各个维度的积分模型之后,得出的排序。就不一定依照同一时候 含有 中国
、联想 、 笔记本优先级排序了。

。有些仅仅包括 中国  这个词的优先级非常高 也有可能。这样的结果排序 明显不能理解和符合用户的意思。

怎样合理的控制solr查询的命中的数量和质量???

在上篇文章中,提到了两种关于solr 对短语、短句(非关键词)的搜索精度解决方式,solr控制多词联合查询命中的数量

可是上面攻克了返回精度的问题。

可是设置mm匹配精度 或者全词匹配defaultOperator=“AND”。df和qf 自己定义的排序 就不起作用了。

默认情况下,Solr查询语法仅仅有两种形式:关键词或者以空格分隔的关键词组。

当查询英文时,英文本身就是以空格来区分词的,所以Solr就能直接获取英文词并组装Query。可是中文句子中间没有空格,Solr查询时把整个句子交给Query。然后由Query再依照Field来分词、查询。这样就丧失了DisMax中qf所能带来的优点。

所以:思考了这么一种思路。对“中国联想笔记本”分词之后。对每一个词单元
中间接一个空格,就能够满足控制搜索词匹配度的前提下。提供自己定义排序。

这个时候就须要重写lucene的默认的queryParser 。

版本号:solr4.10.3

solrconfig.xml代码

<span style="font-size:14px;"><str name="defType">myparser</str></span>
<span style="font-size:14px;"> <!-- 自己定义queryParser -->
<queryParser name="myparser" class="com.lubanec.util.MyQParserPlugin"/></span>

重写QParserPlugin和DisMaxQParser

<span style="font-size:14px;">package com.lubanec.util;

import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.QParser;
import org.apache.solr.search.QParserPlugin; public class MyQParserPlugin extends QParserPlugin { public void init(NamedList args) {
} public QParser createParser(String qstr, SolrParams localParams,
SolrParams params, SolrQueryRequest req) {
return new MyQParser(qstr, localParams, params, req);
}
}
</span>
<span style="font-size:14px;">package com.lubanec.util;

import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.DisMaxQParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class MyQParser extends DisMaxQParser {
private static Logger log = LoggerFactory.getLogger(MyQParser.class); public MyQParser(String qstr, SolrParams localParams, SolrParams params,
SolrQueryRequest req) {
super(qstr, localParams, params, req);
Analyzer analyzer = req.getSchema().getQueryAnalyzer();
if (null == analyzer)
return;
StringBuilder norm = new StringBuilder();
// log.info("before analyzer, qstr=" + this.qstr);
try {
TokenStream ts = analyzer.tokenStream(req.getSchema().getDefaultSearchFieldName(), new StringReader(this.qstr));
ts.reset();
while (ts.incrementToken()) {
CharTermAttribute termAttribute = ts.getAttribute(CharTermAttribute.class);
// System.out.println(termAttribute.toString());
norm.append(new String(termAttribute.toString())).append(" ");
}
ts.end();
ts.close();
} catch (Exception ex) {
log.info("Ex=" + ex);
}
if (norm.length() > 0)
this.qstr = norm.toString();
// log.info("after analyzer, qstr=" + this.qstr);
} }
</span>

最好的办法,就把默认的ExtendedDismaxQParser复制过来,加上本地代码。。保留dismax全部功能。

例如以下:

在ExtendedDismaxQParser构造方法中增加上面那部分代码;

  public ExtendedDismaxQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
super(qstr, localParams, params, req);
Analyzer analyzer = req.getSchema().getQueryAnalyzer();
if (null == analyzer)
return;
StringBuilder norm = new StringBuilder();
try {
TokenStream ts = analyzer.tokenStream(req.getSchema()
.getDefaultSearchFieldName(), new StringReader(this.qstr));
ts.reset();
while (ts.incrementToken()) {
CharTermAttribute termAttribute = ts.getAttribute(CharTermAttribute.class);
norm.append(new String(termAttribute.toString())).append(" ");
}
ts.end();
ts.close();
} catch (Exception ex) {
ex.printStackTrace();
}
if (norm.length() > 0)
this.qstr = norm.toString();
config = this.createConfiguration(qstr,localParams,params,req);
}

OK。。结束!

解决solr搜索多词匹配度和排序方案的更多相关文章

  1. solr如何让全词匹配结果在最前面

    在全文搜索中默认排序是按照匹配度权值score排序的,权值越大位置越靠前,那为什么有很多时候全词匹配反而不在最前面那,其实很简单因为全词匹配权值也就是100,但是还有很多权值大于100的排在了前面. ...

  2. solr搜索之搜索精度问题我已经尽力了!!!

    solr搞了好久了,没啥进展,没啥大的突破,但是我真的尽力了! solr7可能是把默认搜索方式去掉了,如下: 在solr7里找了半天以及各种查资料也没发现这个默认搜索方式,后来想,可能是被edisma ...

  3. 深度学习解决NLP问题:语义相似度计算

    在NLP领域,语义相似度的计算一直是个难题:搜索场景下query和Doc的语义相似度.feeds场景下Doc和Doc的语义相似度.机器翻译场景下A句子和B句子的语义相似度等等.本文通过介绍DSSM.C ...

  4. Solr搜索解析及查询解析器用法概述

    一.简介 大多数查询都使用 了标准的Solr语法.这种语法是Solr最常见的,由默认查询解析器负责处理.Solr的默认查询解析器是Lucene查询解析器[LuceneQParserPlugin类实现] ...

  5. Solr搜索结果高级设置

    一.选择响应格式 XML是Solr的默认响应格式.从Solr的角度看,什么样的响应格式并不重要.Solr可以返回XML.JSON.Ruby.Python.PHP.二进制Java等,甚至是自定义格式.使 ...

  6. 关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造)

    关于Solr搜索标点与符号的中文分词你必须知道的(mmseg源码改造) 摘要:在中文搜索中的标点.符号往往也是有语义的,比如我们要搜索“C++”或是“C#”,我们不希望搜索出来的全是“C”吧?那样对程 ...

  7. 什么是Solr搜索

    什么是Solr搜索 一.Solr综述   什么是Solr搜索 我们经常会用到搜索功能,所以也比较熟悉,这里就简单的介绍一下搜索的原理. 当然只是介绍solr的原理,并不是搜索引擎的原理,那会更复杂. ...

  8. Solr搜索技术

    Solr搜索技术 今日大纲 回顾上一天的内容: 倒排索引 lucene和solr的关系 lucene api的使用 CRUD 文档.字段.目录对象(类).索引写入器类.索引写入器配置类.IK分词器 查 ...

  9. Solr系列五:solr搜索详解(solr搜索流程介绍、查询语法及解析器详解)

    一.solr搜索流程介绍 1. 前面我们已经学习过Lucene搜索的流程,让我们再来回顾一下 流程说明: 首先获取用户输入的查询串,使用查询解析器QueryParser解析查询串生成查询对象Query ...

随机推荐

  1. Speex回声消除原理深度解析

    这里假设读者具有自适应滤波器的基础知识.Speex的AEC是以NLMS为基础,用MDF频域实现,最终推导出最优步长估计:残余回声与误差之比.最优步长等于残余回声方差与误差信号方差之比,这个结论可以记下 ...

  2. PHP无限级分类实现(递归+非递归)

    <?php /** * Created by PhpStorm. * User: qishou * Date: 15-8-2 * Time: 上午12:00 */ //准备数组,代替从数据库中检 ...

  3. 数据通讯与网络 第五版第24章 传输层协议-TCP协议部分要点

    上一博客记录了UDP协议的关键要点,这部分记录TCP协议的关键要点. 24.3 传输控制协议(TRANSMISSION CONTROL PROTOCOL) TCP(Transmission Contr ...

  4. MacOS 升级后pod 出现的问题

    -bash: /usr/local/bin/pod: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby: bad ...

  5. 【python】数组去重

    直接用set就行,比如: l = [1, 1, 2, 2, 3, 4, 5] s = set(l) c = [i for i in s] print c 结果为: [1, 2, 3, 4, 5] 其中 ...

  6. 【备份工具】mydumper

    Mydumper主要特性:是一个针对MySQL的高性能多线程备份和恢复工具,开发人员主要来自MySQL,Facebook,SkySQL公司. 特性: 1:轻量级C语言写的 2:执行速度比mysqldu ...

  7. ASP.NET Cache 实现依赖Oracle的缓存策略

    ASP.NET 中的缓存提供了对SQL依赖项的支持,也就是说当SQL SERVER数据库中的表或行中的数据被更改后,缓存中的页面就失效,否则,页面输出可一直保留在缓存当中.这确实为程序员提供了方便.但 ...

  8. 【原创】redhat5安装oracle10g

    安装缺失的包: 用 root 用户身份运行以下命令: rpm -q gcc make binutils openmotif setarch compat-db compat-gcc compat-gc ...

  9. ASP.NET刷新页面的六种方法

    第一: private void Button1_Click( object sender, System.EventArgs e )   {      Response.Redirect( Requ ...

  10. WebGL画点程序v2

    本文程序实现画一个点的任务,如下图.其中,点的位置坐标由Javascript传到着色器程序中,而不是直接给定("硬编码")在顶点着色器中. 整个程序包含两个文件,分别是: 1. H ...