之前一直用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中的请求处理器、搜索组件以及查询解析器等关键组成部分。 #### 请求处理程序(Request Handlers) **请求处理程序** 是Solr的核心组件之一,用于接收客户端请求并返回相应的结果。它们...
- Solr支持丰富的查询语法,如Lucene Query Parser语法、DisMax查询解析器等。 - 可以自定义排序规则,根据相关性、时间或其他字段值进行结果排序。 6. **高级特性** - ** faceting(聚类)**:允许用户按类别...
- **查询语法**:Solr支持多种查询语法,如Lucene查询语法、DisMax查询解析器、edismax查询解析器等。 - **高亮显示**:Solr可以高亮显示搜索结果中的匹配部分,提高用户体验。 - **排序与评分**:Solr可以根据...
DisMax是针对简单易用而优化的查询解析器,扩展的DisMax解析器提供了更多控制搜索结果排序的参数。函数查询允许将文档字段值作为参数,根据计算结果对查询进行过滤。局部参数则提供了一种方式来在查询中动态地覆盖...
1. **Query Syntax**:Solr支持多种查询语法,包括标准查询解析器(QParser)、Lucene查询语法(LQ)和DisMax查询解析器。 2. **Faceting**:提供分类统计,帮助用户快速了解搜索结果的分布情况。 3. **Highlighting...
5. **请求处理器与查询解析器**:Solr提供了丰富的请求处理器和查询解析器,4.2.0版本可能包含了新的或优化的解析器,如DisMax和EDismax,它们能够更好地处理用户输入,提高搜索体验。 6. **XML和JSON API增强**:...
- **高级查询语法**: 介绍 Solr 的 QueryParser 和 DisMax 查询解析器,以及如何使用它们来构建复杂的查询。 - **结果排序与分组**: 掌握排序和分组查询结果的方法,以及如何实现自定义排序策略。 4. **性能调优**...
4. **Query Parser(查询解析器)**:Solr支持多种查询语法,如标准查询解析器和DisMax查询解析器,用于处理用户的搜索请求。 #### 三、Solr安装配置步骤 1. **环境准备**:确保Java环境已安装配置好,因为Solr是...
- **Query Parsers**:允许自定义查询解析器,如 DisMax QParser 和 Function QParsers,支持多种查询类型和功能查询。 - **Text Analysis**:分析器、分词器和过滤器插件用于处理文本输入,如 Whitespace ...
Solr的查询能力强大且灵活,支持多种查询语法,包括标准查询解析器(Standard Query Parser)、简写查询解析器(DisMax Query Parser)等。此外,Solr还支持自定义查询解析器和过滤器,以满足特定的查询需求。用户...
- **Solr 插件 JAR**:可能包含了一些预定义的插件,如查询解析器、过滤器和请求处理器。 - **依赖 JAR**:其他第三方库的 JAR 文件,如用于 JSON 或 XML 处理的库。 在进行 Solr 测试时,这些 JAR 文件将被添加到...
- **DisMax 查询解析器**:提供更高级的功能,如自动完成、拼写检查等。 - **函数查询**:允许使用特定函数对结果进行排序或过滤。 #### 七、Solr 的优化技巧 - **缓存策略**:合理利用缓存可以显著提升查询性能。 ...
### Solr 学习文档知识点解析 #### 一、Solr 概述 Solr 是一个高度可扩展的、高性能的、开源的企业级搜索平台,它基于 Lucene 构建,能够提供强大的全文检索功能。Solr 可以用于各种应用环境中,包括网站搜索、...
4. **查询与搜索**:学习Solr的查询语法,如使用Lucene Query Parser、DisMax查询解析器,以及如何构造复杂的查询表达式,如布尔运算符、短语匹配、范围查询等。 5. **结果排序与评分**:理解如何自定义排序规则,...