转载请标明出处: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. @PathVariable注解的使用和@Requestparam

    一. @PathVariable @PathVariable这是一个路径映射格式的书写方式注解,在类映射路径的后加上/{对应方法参数中属性@PathVariable("code") ...

  2. My97DatePicker 动态设置有效/无效日期

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding= ...

  3. Mysql Event 自动分表

    create table TempComments Like dycomments; 上述 SQL语句创建的新表带有原表的所有属性,主键,索引等. 自动分表怎么做呢? 使用上述语句自动创建分表. 那么 ...

  4. openMSP430之io_test

    openMSP430: IO functionality test with interupt #include "omsp_system.h" volatile char shi ...

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

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

  6. C++ Rand()各种实现

    参考链接:http://www.cplusplus.com/reference/cstdlib/rand/ 使用实例: v1 = rand() % 100; // v1 in the range 0 ...

  7. promise原理及使用方法

    Promise 的含义 所谓Promise ,简单说就是一个容器,里面保存着某个未来才回结束的事件(通常是一个异步操作)的结果.从语法上说,Promise是一个对象,从它可以获取异步操作的消息. re ...

  8. webpack学习(六)—webpack+react+es6(第2篇)

    接上篇        webpack学习(五)—webpack+react+es6(第1篇) 本文做个简单的图片加文字的页面.其中,配置文件跟上篇一致.项目结构: index.html <!DO ...

  9. 【转】虚拟化(三):vsphere套件的安装注意及使用

    vsphere套件里面主要的组件有esxi.vcenter server .vsphere client和vsphere web client. vcenter做为vsphere套件的核心管理成员之一 ...

  10. python tips:作为dict的key的类

    Python的dict由hash实现,解决hash冲突的方法是二次探查法.hash值相同的元素会形成链表.所以dict在查找key时,首先获取hash值,直接得到链表的表头:而后在链表中查找等于key ...