转载请标明出处: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. EF6 自定义迁移表名

    在下列代码片段中已经EF6迁移表的表名更改为 MigrationHistory注意:下代码片段建议和DbContext同程序集 public class ModelConfiguration : Db ...

  2. SPOJ GSS1 & GSS3&挂了的GSS5

    线段树然后yy一下,搞一搞. GSS1: 题意:求最大区间和. #include <cstdio> #include <algorithm> using namespace s ...

  3. 牛客练习赛19 -E-托米的饮料

    题目描述 好了,现在是小托米的故事啦~~~ 可爱的小托米得到了n瓶饮料. 但他不小心把开盖的工具弄丢了,所以他只能利用饮料瓶来开盖. 已知第i个瓶子的品牌为ai,且其能打开bi品牌的瓶子. 问有几瓶饮 ...

  4. Spring 整合 Redis (零配置) 的简单使用

    pom.xml <!--jedis--> <dependency> <groupId>redis.clients</groupId> <artif ...

  5. Android Fragment间的广播消息接收

    这种方式不用在配置文件加东西,我比较喜欢. 广播注册,可以写在Activity(onCreate),也可以写在Fragment(onActivityCreated)里. LocalBroadcastM ...

  6. java与安卓中的回调callback学习笔记

    1.回调的简单设计如下: package com.listercai.top; public class A { private CallBack callBack; private AnotherC ...

  7. 【Oracle】客户端监听配置

    首先找到oracle软件安装的目录,找到\product\11.2.0\client_1\network\admin,打开tnsnames.ora文件: 粘贴一下内容: LISTENER= (DESC ...

  8. 分布式机器学习框架:MxNet

    MxNet官网: http://mxnet.readthedocs.io/en/latest/ 前言: caffe是很优秀的dl平台.影响了后面很多相关框架. cxxnet借鉴了很多caffe的思想. ...

  9. 时序分析:串匹配-KMP算法

    图像处理与模式识别的教科书使用大量的章节来描述空域的模式识别方法.从图像底层特征提取.贝叶斯方法到多层神经网络方法,一般不讨论到对象随时间变化的情况,视频处理应用和在线学习方法使研究对象开始向时域延伸 ...

  10. spring中的prop、set、list、map

    props.set.list.map这些事spring配置文件中很常见的标签,下面说下各自的适用场合. props:用于键值对,建和值都为string类型. <property name=&qu ...