【问题标题】:Spring Data for Apache Solr Extended DisMax ParametersApache Solr 扩展 DisMax 参数的 Spring Data
【发布时间】:2017-03-16 18:51:22
【问题描述】:

我正在尝试在 Spring Data Solr 生成的 Solr 查询中添加以下参数 (qf,bq)。

Solr 参数为:

qf => Spring Data Solr Method?
bq => Spring Data Solr Method?

我找到了以下方法

fq => addFilterQuery
fl => addProjectionOnField
defType => setDefType
qt => setRequestHandler

我看到一个未解决的问题 qf https://jira.spring.io/browse/DATASOLR-153

如何将 qf 和 bq 参数添加到使用 Spring Data Solr 构建的 Solr 查询中。

谢谢

【问题讨论】:

    标签: solr spring-data spring-data-solr


    【解决方案1】:

    您可以在模板级别使用SolrCallback 访问SolrClient 并从那里执行查询,或者为自定义查询类型注册您自己的QueryParser

    可能是这样的:

    @Bean
    public SolrTemplate solrTemplate(SolrClient client) {
    
        SolrTemplate template = new SolrTemplate(client);
        template.registerQueryParser(EdismaxQuery.class, new EdisMaxQueryParser());
        return template;
    }
    
    class EdismaxQuery extends SimpleQuery {
        // ... add stuff you need. Maybe `autoRelax`
    }
    
    class EdisMaxQueryParser extends QueryParserBase<EdismaxQuery> {
    
        DefaultQueryParser defaultQueryParser = new DefaultQueryParser();
    
        @Override
        public SolrQuery doConstructSolrQuery(EdismaxQuery source) {
    
            // just use the default parser to construct the query string in first place.
            SolrQuery target = defaultQueryParser.constructSolrQuery(source);
    
            // add missing parameters
            target.add("defType", "edismax");
            target.add("qf", source....);
    
            return target;
        }
    }
    

    【讨论】:

    • 我收到了这个错误:org.springframework.data.solr.core.QueryParserBase$NamedObjectsQuery cannot be cast to EdismaxQuery
    【解决方案2】:

    Spring Data Solr API 4.0 有一些变化,因此您可能需要稍微更改一下注册自己的QueryParser 的方式。

    @Bean
    public SolrTemplate solrTemplate(SolrClient client) {
        SolrTemplate template = new SolrTemplate(client);
        solrTemplate.registerQueryParser(EdismaxQuery.class, new EdisMaxQueryParser(new SimpleSolrMappingContext()));
        return template;
    }
    
    public static class EdismaxQuery extends SimpleQuery {
        private String defaultField;
        private String minimumShouldMatch;
        private String boostQuery;
        private String queryField;
    
        public EdismaxQuery(String queryString) {
            super(queryString);
        }
        //... typical getter/setter
    }
    
    public static class EdisMaxQueryParser extends QueryParserBase<AbstractQueryDecorator> {
    
        private final DefaultQueryParser defaultQueryParser;
    
        public EdisMaxQueryParser(MappingContext<? extends SolrPersistentEntity<?>, SolrPersistentProperty> mappingContext) {
            super(mappingContext);
            defaultQueryParser = new DefaultQueryParser(mappingContext);
        }
    
        @Override
        public SolrQuery doConstructSolrQuery(AbstractQueryDecorator queryDecorator, Class<?> domainType) {
            // for some reason the API wrapped our query object with NamedObjectsQuery, so we need to unwrapped/get our actual query object first
            EdismaxQuery query = (EdismaxQuery) queryDecorator.getDecoratedQuery();
    
            // use defaultQueryParser to populate basic query parameters
            SolrQuery solrQuery = defaultQueryParser.doConstructSolrQuery(query, domainType);
    
            // set our own 'extra' parameter
            if (query.getDefaultField() != null) { 
                solrQuery.add("df", query.getDefaultField());
            }
            if (query.getMinimumShouldMatch() != null) {
                solrQuery.add("mm", query.getMinimumShouldMatch());
            }
            if (query.getQueryField() != null) {
                solrQuery.add("qf", query.getQueryField());
            }
            if (query.getBoostQuery() != null) {
                solrQuery.add("bq", query.getBoostQuery());
            }
            //...
    
            return target;
        }
    }
    

    这是使用新 EdismaxQuery 对象进行查询的方式

    EdismaxQuery query = new EdismaxQuery("hello world");
    query.setDefType("edismax");
    query.setRows(3);
    query.setQueryField("text^2");
    query.setMinimumShouldMatch("30%");
    query.setBoostQuery("date:[NOW/DAY-1YEAR TO NOW/DAY]");
    
    Page<ResultBean> results = solrTemplate.query("collection", query, ResultBean.class);
    

    【讨论】:

      【解决方案3】:

      为了避免:

      org.springframework.data.solr.core.QueryParserBase$NamedObjectsQuery 无法转换为 EdismaxQuery

      EdisMaxQueryParser 应该如下所示:

      class EdisMaxQueryParser extends QueryParserBase {
          @Override
          public SolrQuery doConstructSolrQuery(SolrDataQuery source) {
              // your stuff
          }
      }
      

      【讨论】:

        【解决方案4】:

        如果您要为每个选择查询添加静态 qf 表达式,可以在 solrconfig.xml 中完成:

        <requestHandler name="/select" class="solr.SearchHandler">
        <lst name="defaults">
          ...
        </lst>
        <lst name="appends">
          <str name="defType">edismax</str>
          <str name="qf">offerId^100 vendorCode^100</str>
        </lst>
        ...
        </requestHandler>
        

        【讨论】:

          【解决方案5】:

          您可以将 edismax 库用于 spring-solr https://github.com/KmSYS/edismax-solr-spring

          但是要克服在 afterPropertiesSet() 中覆盖已注册的查询解析器的问题,您需要在配置类中添加以下 bean,

              @Bean
              public SolrTemplate solrTemplate(SolrClient client) {
                  SolrTemplate template = new SolrTemplate(client) {
          
                      @Override
                      public void afterPropertiesSet() {
                          super.afterPropertiesSet();
                          registerQueryParser(SimpleEdismaxQuery.class, new EdisMaxQueryParser(new SimpleSolrMappingContext()));
                      }
                  };
          
                  template.afterPropertiesSet();
                  return template;
              }
          

          另外,https://github.com/KmSYS/edismax-solr-spring-sample 的示例代码

          http://www.kmsys.tech/solr/edixmax-query-parser-template.html

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-22
            • 1970-01-01
            • 1970-01-01
            • 2012-07-15
            • 2013-01-23
            • 1970-01-01
            相关资源
            最近更新 更多