`
suichangkele
  • 浏览: 201444 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

solr中的dismax解析器

    博客分类:
  • solr
阅读更多
之前一直用dismax,但是一直没有看看他到底是怎么实现的,今天终于看了一遍源码,记个笔记,方便以后查阅。
当我们使用defType=dismax的时候就会使用到DisMaxQParser这个类,他是一个QParser,用于根据用户的输入解析为一个Query类的实例。我们看看他的解析方法:
  @Override
  public Query parse() throws SyntaxError {
      parsed = true;
      SolrParams solrParams = SolrParams.wrapDefaults(localParams, params);// 将localParams域params合并。优先使用localParams
    
      queryFields = parseQueryFields(req.getSchema(), solrParams);//获得所有的qf,即要匹配的域已经各个域的boost,queryFields是个map,key是String,value是float。
    
      /*
       * the main query we will execute. we disable the coord because this query is an artificial construct
       */
      BooleanQuery query = new BooleanQuery(true);//最后形成的BooleanQuery,
    
      boolean notBlank = addMainQuery(query, solrParams);//向最后的BooleanQuery中添加mainQuery,mainQuery包含两部分,一个是匹配的qf,一个是匹配的pf,等会再看
      if (!notBlank) return null;
      addBoostQuery(query, solrParams);//向最后的booleanQuery中添加boostQuery,用于提高某些文档的得分
      addBoostFunctions(query, solrParams);//向最后的booleaQuery中添加boostFunction的query,用于提高某些文档的得分
    
      return query;
  }
 下面我们一个一个方法的来看:
1、addMainQuery:
 protected boolean addMainQuery(BooleanQuery query, SolrParams solrParams) throws SyntaxError {
    
    Map<String,Float> phraseFields = SolrPluginUtils.parseFieldBoosts(solrParams.getParams(DisMaxParams.PF));//获得pf的域以及每个域的boost
    float tiebreaker = solrParams.getFloat(DisMaxParams.TIE, 0.0f);//获得参数中的tie,也就是disjunctionMaxQuery中的tie,用于计算最后的得分。默认是0.0f,也就是只关心最大的得分,不关心其他的得分。
    
    /*
     * a parser for dealing with user input, which will convert things to DisjunctionMaxQueries
     */
    SolrPluginUtils.DisjunctionMaxQueryParser up = getParser(queryFields, DisMaxParams.QS, solrParams, tiebreaker);//这个是解析queryFields的queryParser,也即是产生由参数中的查询字符串和qf以及qs(query slope)形成的query的queryParser。
    
    /* for parsing sloppy phrases using DisjunctionMaxQueries */
    SolrPluginUtils.DisjunctionMaxQueryParser pp = getParser(phraseFields, DisMaxParams.PS, solrParams, tiebreaker);//这个和上面的up差不多,只不过他是产生由查询字符串,phraseFields,以及ps(phrase fileds)形成的query的queryParser。
    
    /* * * Main User Query * * */
    parsedUserQuery = null;
    String userQuery = getString();//前台输入的字符串。
    altUserQuery = null;
    if (userQuery == null || userQuery.trim().length() < 1) {// 优先使用q,如果没有则使用q.alt。之后的逻辑和使用userQuery的逻辑一样。
      // If no query is specified, we may have an alternate
      altUserQuery = getAlternateUserQuery(solrParams);
      if (altUserQuery == null) return false;
      query.add(altUserQuery, BooleanClause.Occur.MUST);
    } else {
      // There is a valid query string
      userQuery = SolrPluginUtils.partialEscape(SolrPluginUtils.stripUnbalancedQuotes(userQuery)).toString();//删除不对称的引号(逻辑是如果是奇数个引号,则将引号全部删了),然后过滤特殊字符(比如*、:、!、@、(、{,【,[),只保留" + -。
从这里可以看出,使用*:*是什么也搜不到的,也就是他不支持luceneQParser的普通的功能,仅仅支持+、-两个特殊的字符。
      userQuery = SolrPluginUtils.stripIllegalOperators(userQuery).toString();//删掉过多的+、-
      
      parsedUserQuery = getUserQuery(userQuery, up, solrParams);//用up这个queryParser解析成query,并设置mm这个属性(也就是如果在查询字符串中有用空格分开的字符串的话,对于optional的booleanClause必须要满足的个数),因为可能parsdUserQuery是一个booleanquery
      query.add(parsedUserQuery, BooleanClause.Occur.MUST);//将解析的parsedUserQuery添加到最后的query中,设置为must,即必须出现。
      
      Query phrase = getPhraseQuery(userQuery, pp);//这个和上面的getUserQuery是一样的,只不过没有设置mm的步骤。
      if (null != phrase) {
        query.add(phrase, BooleanClause.Occur.SHOULD);//如果有phrase,则添加到最后的booleanQuery中,设置为optional的,即仅仅用于将那些匹配的document提高得分。
      }
    }
    return true;
  }
 2、addBoostQuery:
  protected void addBoostQuery(BooleanQuery query, SolrParams solrParams) throws SyntaxError {
    boostParams = solrParams.getParams(DisMaxParams.BQ);//从请求参数中获得bq
    boostQueries = null;
    if (boostParams != null && boostParams.length > 0) {
      boostQueries = new ArrayList<>();//最后形成的boost query。
      for (String qs : boostParams) {
        if (qs.trim().length() == 0) continue;
        Query q = subQuery(qs, null).getQuery();//这个是使用默认的queryParser对qs进行解析,解析为一个query,默认的queryParser即QParserPlugin中的LuceneQParserPlugin。
        boostQueries.add(q);//
      }
    }
//下面是将上面形成的boost query添加到最终的booleanquery中去,用于提高命中的document的得分。
    if (null != boostQueries) {
      if (1 == boostQueries.size() && 1 == boostParams.length) {//如果生成的boostquery仅仅有一个子query
        Query f = boostQueries.get(0);
        if (1.0f == f.getBoost() && f instanceof BooleanQuery) {
          /*
           * if the default boost was used, and we've got a BooleanQuery extract the subqueries out and use them
           * directly
           */
          for (Object c : ((BooleanQuery) f).clauses()) {
            query.add((BooleanClause) c);
          }
        } else {
          query.add(f, BooleanClause.Occur.SHOULD);
        }
      } else {
        for (Query f : boostQueries) {
          query.add(f, BooleanClause.Occur.SHOULD);
        }
      }
    }
  }
 3、addFunctionQuery
  protected void addBoostFunctions(BooleanQuery query, SolrParams solrParams) throws SyntaxError {
    String[] boostFuncs = solrParams.getParams(DisMaxParams.BF);//获得bf参数,即函数查询的参数,
    if (null != boostFuncs && 0 != boostFuncs.length) {
      for (String boostFunc : boostFuncs) {
        if (null == boostFunc || "".equals(boostFunc)) continue;
        Map<String,Float> ff = SolrPluginUtils.parseFieldBoosts(boostFunc);
        for (String f : ff.keySet()) {
          Query fq = subQuery(f, FunctionQParserPlugin.NAME).getQuery();//指定了解析器
          Float b = ff.get(f);
          if (null != b) {
            fq.setBoost(b);
          }
          query.add(fq, BooleanClause.Occur.SHOULD);//将解析的query作为一个optional的添加到最终的query中
        }
      }
    }
  }
就这样就看完了dismax,qf,qs是限定要获取的数据的,体现在他在最终的booleanQuery中是must,pf 、ps是用来增加命中的得分的,一般都是将ps设置的比qs大得多,bq也是用来增加命中的document的得分的,bf同样如此。
 
分享到:
评论

相关推荐

    Solr In Action 第七章 中文版

    本章的重点在于理解和运用Solr中的请求处理器、搜索组件以及查询解析器等关键组成部分。 #### 请求处理程序(Request Handlers) **请求处理程序** 是Solr的核心组件之一,用于接收客户端请求并返回相应的结果。它们...

    solr-6.6.0压缩包

    - Solr支持丰富的查询语法,如Lucene Query Parser语法、DisMax查询解析器等。 - 可以自定义排序规则,根据相关性、时间或其他字段值进行结果排序。 6. **高级特性** - ** faceting(聚类)**:允许用户按类别...

    solr-8.3.0.tgz

    - **查询语法**:Solr支持多种查询语法,如Lucene查询语法、DisMax查询解析器、edismax查询解析器等。 - **高亮显示**:Solr可以高亮显示搜索结果中的匹配部分,提高用户体验。 - **排序与评分**:Solr可以根据...

    Apache Solr Reference Guide 6.0.pdf

    DisMax是针对简单易用而优化的查询解析器,扩展的DisMax解析器提供了更多控制搜索结果排序的参数。函数查询允许将文档字段值作为参数,根据计算结果对查询进行过滤。局部参数则提供了一种方式来在查询中动态地覆盖...

    solr-6.4.1 安装包.zip

    1. **Query Syntax**:Solr支持多种查询语法,包括标准查询解析器(QParser)、Lucene查询语法(LQ)和DisMax查询解析器。 2. **Faceting**:提供分类统计,帮助用户快速了解搜索结果的分布情况。 3. **Highlighting...

    solr-4.2.0

    5. **请求处理器与查询解析器**:Solr提供了丰富的请求处理器和查询解析器,4.2.0版本可能包含了新的或优化的解析器,如DisMax和EDismax,它们能够更好地处理用户输入,提高搜索体验。 6. **XML和JSON API增强**:...

    Apache.Solr.3.1.Cookbook

    - **高级查询语法**: 介绍 Solr 的 QueryParser 和 DisMax 查询解析器,以及如何使用它们来构建复杂的查询。 - **结果排序与分组**: 掌握排序和分组查询结果的方法,以及如何实现自定义排序策略。 4. **性能调优**...

    solr教程,绝对物有所值

    4. **Query Parser(查询解析器)**:Solr支持多种查询语法,如标准查询解析器和DisMax查询解析器,用于处理用户的搜索请求。 #### 三、Solr安装配置步骤 1. **环境准备**:确保Java环境已安装配置好,因为Solr是...

    Apache Solr lucene 搜索模块设计实现

    - **Query Parsers**:允许自定义查询解析器,如 DisMax QParser 和 Function QParsers,支持多种查询类型和功能查询。 - **Text Analysis**:分析器、分词器和过滤器插件用于处理文本输入,如 Whitespace ...

    solr开发指南.zip

    Solr的查询能力强大且灵活,支持多种查询语法,包括标准查询解析器(Standard Query Parser)、简写查询解析器(DisMax Query Parser)等。此外,Solr还支持自定义查询解析器和过滤器,以满足特定的查询需求。用户...

    solr-jars.zip

    - **Solr 插件 JAR**:可能包含了一些预定义的插件,如查询解析器、过滤器和请求处理器。 - **依赖 JAR**:其他第三方库的 JAR 文件,如用于 JSON 或 XML 处理的库。 在进行 Solr 测试时,这些 JAR 文件将被添加到...

    Apache Solr Beginner's Guide

    - **DisMax 查询解析器**:提供更高级的功能,如自动完成、拼写检查等。 - **函数查询**:允许使用特定函数对结果进行排序或过滤。 #### 七、Solr 的优化技巧 - **缓存策略**:合理利用缓存可以显著提升查询性能。 ...

    Solr.学习文档

    ### Solr 学习文档知识点解析 #### 一、Solr 概述 Solr 是一个高度可扩展的、高性能的、开源的企业级搜索平台,它基于 Lucene 构建,能够提供强大的全文检索功能。Solr 可以用于各种应用环境中,包括网站搜索、...

    solr-book:Solr书籍范例程式码

    4. **查询与搜索**:学习Solr的查询语法,如使用Lucene Query Parser、DisMax查询解析器,以及如何构造复杂的查询表达式,如布尔运算符、短语匹配、范围查询等。 5. **结果排序与评分**:理解如何自定义排序规则,...

Global site tag (gtag.js) - Google Analytics