在Spring Data Solr

时间:2016-01-11 10:46:32

标签: java spring solr spring-data-solr

我在我的项目中使用Spring Data Solr。在某些情况下,生成的对Solr的查询太大(例如15Kb +)并导致Solr异常。此解决方案:http://codingtricks.fidibuy.com/participant/join/54fce329b760506d5d9e7db3/Spring-Data-Solr-cannot-handle-long-queries 一些疑问仍然失败。 由于通过POST直接将这些查询发送到Solr工作正常,我选择了朝这个方向努力。我没有在Spring Data Solr中找到任何方法来为查询配置首选方法(GET / POST)。因此,我提出了以下解决方案:我扩展了SolrServer

public class CustomSolrServer extends HttpSolrServer {      
    public CustomSolrServer(String home, String core) {
        super(home);
        setCore(core);
    }

    @Override
    public QueryResponse query(SolrParams params) throws SolrServerException {
        METHOD method = METHOD.GET;
        if (isBigQuery(params)) {
            method = METHOD.POST;
        }
        return new QueryRequest( params, method ).process( this );
    }       
}

(跳过一些细节,setCore()和isBigQuery()也是微不足道的并且也被跳过了) 并在SolrConfiguration.class中将其用作SolrServer bean:

@Configuration
@EnableSolrRepositories(basePackages = { "com.vvy.repository.solr" }, multicoreSupport=false)
@Import(value = SolrAutoConfiguration.class)
@EnableConfigurationProperties(SolrProperties.class)

public class SolrConfiguration {

    @Autowired
    private SolrProperties solrProperties;

    @Value("${spring.data.solr.core}")
    private String solrCore;

    @Bean
    public SolrServer solrServer() {
        return new CustomSolrServer(solrProperties.getHost(),solrCore) ;
    }   
}

这样可行,但有一些缺点:我必须将multiCoreSupport设置为false。之所以这样做是因为当Spring Data Solr从接口实现存储库时,其上的multiCoreSupport使用MultiCoreSolrServerFactory并尝试为每个核心存储一个服务器,这是通过将它们克隆到保留映射来完成的。当然,它在定制的SolrServer上崩溃,因为SolrServerUtils不知道如何克隆()它。另外,我必须手动设置核心而不是享受Spring Data从实体类的@SolrDocument注释参数中提取它。

以下是问题 1)主要问题和一般问题:有没有合理的方法来解决Spring Data Solr中过长查询的问题(或者更具体地说,使用POST而不是GET)? 2)次要的:有没有合理的方法在Spring Data Solr中自定义SolrServer并保持multiCoreSupport?

1 个答案:

答案 0 :(得分:1)

回答Q1:是的,你可以使用POST代替GET。

回答Q2:是的,你已经做了一半。除了以下:

1)你必须将'CustomSolrServer'重命名为'HttpSolrServer',你可以检查方法

  

org.springframework.data.solr.server.support.SolrServerUtils #clone(T,java.lang.String)

有理由。

2)你不必指定具体的核心名称.U可以使用注释指定核心名称

  

org.springframework.data.solr.core.mapping.SolrDocument

对应的solr模型。

3)设置multicoreSupport = true

根据您的课程样本,它们应如下所示:

package com.x.x.config;

import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.params.SolrParams;

public class HttpSolrServer extends org.apache.solr.client.solrj.impl.HttpSolrServer {

    public HttpSolrServer(String host) {
        super(host);
    }

    @Override
    public QueryResponse query(SolrParams params) throws SolrServerException {
        SolrRequest.METHOD method = SolrRequest.METHOD.POST;
        return new QueryRequest(params, method).process(this);
    }
}


@Configuration
@EnableSolrRepositories(basePackages = { "com.vvy.repository.solr" }, multicoreSupport=true)
@Import(value = SolrAutoConfiguration.class)
@EnableConfigurationProperties(SolrProperties.class)

public class SolrConfiguration {

    @Autowired
    private SolrProperties solrProperties;

    @Bean
    public SolrServer solrServer() {
        return new com.x.x.config.HttpSolrServer(solrProperties.getHost()) ;
    }   
}

ps:最新的spring-data-solr 3.x.x已经支持自定义查询请求方法,请参阅post issue