全面解剖 Solr query 到lucene query

围绕从顶之下,从粗到西的关系认识solr 查询流程和实现细节。最低下定位到queryparse的实现。整个过程围绕信息检索这一思路展开,而不是工程实现来看这个问题。目的从整体结构上认识查询这一块的抽象。这样有具体需求的时候,可以知晓参照按个query、从哪个点注入系统中比较省事,而无需侵入solr、lucene底层。

另外一方面,围绕这个流程看solr在lucene之上的封装,从而一旦完全基于lucene实现自己的结构时候,也可以做到扬长避短,做到有参照、有改进,大大降低细节面临的风险。

1.Solr&Lucene query 执行流程、关系

2 如何扩展Query

3.QueryParse语法树

--》执行流程关系

全面解剖 <wbr>Solr <wbr>query <wbr>到lucene <wbr>query

流程画的不够严谨,争取将相关核心流程展示出来。有两个点需要注意:solrcore、searchcomponent (querycomponet),

--》简要描述模块流程如下

全面解剖 <wbr>Solr <wbr>query <wbr>到lucene <wbr>query

QParserCore作用域,不同的searchHandler都是可以调用的,

searchComponentsearchHandler作用域,默认走StandardRequestHandler,走默认的searchComponent 链。也就是说不同的searchHandler可以走不同的searchComponent。每个searchHandler对于自己的一个路径。


Lucene的排序体系包含了QueryWeightScoreSimilarity几个不同的类

文档匹配阶段主要调用Searcher对象的search方法,在search方法内部,通过直接或者间接调用

Search(Weight weight,Filter filter,Collector collector). 使用search的时候会创建Weight对象,

Weight对象会创建一个score对象,score对象来进行score函数的调用,并将结果保存在Collector对象中。

Scorer 用一个匿名类Collector来收集满足TermQuerydoc

Scorer的代码也表明, 它在遍历所有合法文档时,背后的查询动作是在穷举一个数组:doc[], 而这个数组的来源就是TermDocs.所以高命中耗时。

--》Solr&Lucene已经提供的成熟的各种query

之所以贴出这个简图,目的的是想说明:lucene solr已经实现的query可以说100%能满足你的需要,没有必要折腾搞个新的玩意,lucene 从1.9到现在,query的东西是最稳当的、变更最少的。这是query本身的特征决定的。即使索引结构、引擎如何变,而查询需求、查询规则不变。

已经实现的query,有如下特征,不一定合理,仅供参考

偏向基本的:termquery booleanquery、Functionquery

偏向性能的:MultiTermQuery序列

偏向排序质量的:phrasequery一览

偏向新场景的:spatialquery sqlquery relationquery

全面解剖 <wbr>Solr <wbr>query <wbr>到lucene <wbr>query

全面解剖 <wbr>Solr <wbr>query <wbr>到lucene <wbr>query
--》如何扩展Query

1)扩展Qp:构建相应的Query

abstract class QParserPlugin implements NamedListInitializedPlugin {

public abstract QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req);

public class TermQParserPlugin extends QParserPlugin {

  @Override

  publicQParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {

    returnnewQParser(qstr, localParams, params, req) {

      @Override

      publicQuery parse() {

        String fname = localParams.get(QueryParsing.F);

        FieldType ft = req.getSchema().getFieldTypeNoEx(fname);

        String val = localParams.get(QueryParsing.V);

        BytesRef term = new BytesRef();

        if (ft != null) {

          ft.readableToIndexed(val, term);

        } else {

          term.copyChars(val);

        }

        return new TermQuery(new Term(fname, term));

      }

    };

  }

这里指扩展 QP,扩展的QP 配置在solrconfig.xml中,执行查询的时候指定对于的qp 名称既可以加载相应的QP。  

2)另外一种QP扩展,同时扩展排序规则---filter类型query

public interface PostFilter extends ExtendedQuery {

class FunctionRangeQuery extends SolrConstantScoreQuery implements PostFilter {

  final ValueSourceRangeFilter rangeFilt;

然后在SolrIndexSearcher getDocSet中会根据ExtendedQuery 或者WrappedQuery做调用各自的query 和重写的filter

 

 eg:

solconfig.xml中定义

name="tier" class="com.taobao.tsearcher.qp.CartesianTierQParserPlugin">
  name="geoHash">store_latlon
  name="startTier">4 
name="endTier">19 

查询构造

      query.setQuery("title:广*");
      query.addFilterQuery("{!tier x=30.757575  y=105.70757   dist=10}");   

 基本扩展原理与solr41中的SpatialFilterQParsePlugin\FunctionQParserPlugin 类似,看懂就完全明白如何注入自己的query了,本质是通过本地参数来解析获取对于注入的qp。

2 SQLQuery

 Sql 语句 -->词法(字符串检测)、语法(正则表示规则校验逻辑)分析,语法树翻译对于模板格式下的对应solr查询语法--> solrquery优化

 直接编写Queryparser.jj. 第一步对QueryParse.jj 做词法扩展、语法扩展,第二步 javacc 编辑扩展后的QueryParser.jj,生成对应的词法、语法分析程序。第三步 针对sql query 提供相应的query接口。

3 RelationQuery

1.关系模型设计

2.工程实现设计

[1]关于模型初步的思考

基于词的关联,任务,收集同义词、基于上下文场景的关联扩展。

(1-1)同意扩展

文字与数字转换:一百 /100 一九四九/1949

直接同义词扩展:一脉相传/一脉相承/  一马当先/一马领先

一部分是分词处理,一部分是queryparse处理。

(1-2) 关联扩展 淘宝/杭州/女装。需要分析搜索query自动提取

(2) PageRank & PeopleRank

   针对item设计属性,按照属性计算得分,排序按照离线模型执行sort

(3) VSM

   针对item提取属性值,建索引将属性内容index起来,查询的时候也传入相关属性值,按照多属性值得AND求交集,然后对结果按照向量夹角计算得分,问题转化为直接lucene当前默认模型。

(4)Shape

    每个item定义高纬度坐标,采取类似地理搜索的模型,按照shape做结果集的过滤。

[2]实现思路:

参照上面的分析以filter的形式,改下qparse docidset以及score

QparseFilter sort的扩展,可以理解为FunctionQuery的特例化。

Eg:shape区间交集

将关系映射到平面区间,关系的交集转为平面的交集,从而转义为shape过滤。

Object={ item1item2item3} AND object={item4,item5,item6}

Egsort

结果按照关系维度参数,做类似functionquery的关系模型距离计算。

Egsort

是向量空间模型,输入多个条件,按照向量模型计算得分。

其他高级处理,就是机器学习能自动化相关参数、流程。这一块还没有深入,所以还没有相关经验。

--》lucene Queryparse底层

请参照下面这个链接

http://www.cnblogs.com/forfuture1978/archive/2010/05/08/1730200.html

这里面的分析依然是强大的,尽管在4.*序列有局部调整,单对分析原理、实现细节非常有帮助。

Javacc 基础上扩展qp的详细分析文档见附件上面的链接

javacc本质上和我之前基于solrflux扩展sql支持hl facet一样的。

http://blog.sina.com.cn/s/blog_4d58e3c001013wka.html  solrflux的我之前总结的文档。

相信看完这个文档,大家一定非常清楚solr语法最终如何转为lucene查询的。如何扩展sql也就一目了然。

不过这需要大家提前知晓:文法、词法分析、语法分析这些基本概念和原理,基本上都是理论的公式、形式化的内容

        深入 NLP的内容:例如   词法、语法分析,不妨参考下stanford segment parse   中文预料库机器学习、新词发现、词性分析等等。据了解,很多有司都是在他的基础上扩展、改写的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值