2

I am using Spring Data Solr in my project. In some cases generated queries to Solr are too big (e.g.15Kb+) and cause Solr exceptions. This solution: http://codingtricks.fidibuy.com/participant/join/54fce329b760506d5d9e7db3/Spring-Data-Solr-cannot-handle-long-queries still fails for some queries. Since directly sending those queries to Solr via POST works fine, I chose to work in this direction. I failed to find in Spring Data Solr any way to configure the preferred method (GET/POST) for queries. Therefore, I came to the following solution: I extended 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 );
    }       
}

(some details skipped, setCore() and isBigQuery() are trivial and skipped as well) and use it as SolrServer bean in SolrConfiguration.class:

@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) ;
    }   
}

This works OK, but has a couple of drawbacks: I had to set multiCoreSupport to false. This was done because when Spring Data Solr implements repositories from the interfaces, with multiCoreSupport on it uses MultiCoreSolrServerFactory and tries to store a server per core, which is done by cloning them to the holding map. Naturally, it crashes on a customized SolrServer, because SolrServerUtils doesn't know how to clone() it. Also, I have to set core manually instead of enjoying Spring Data extracting it from @SolrDocument annotation's parameter on the entity class.

Here are the questions 1) the main and general question: is there any reasonable way to solve the problem of too long queries in Spring Data Solr (or, more specifically, to use POST instead of GET)? 2) a minor one: is there a reasonable way to customize SolrServer in Spring Data Solr and yet maintain multiCoreSupport?

VVY
  • 21
  • 4

1 Answers1

1

Answer for Q1:Yes, u can using POST instead of GET.

Answer for Q2:Yes, u already have done a half.Except following:

1)u have to rename 'CustomSolrServer' to 'HttpSolrServer',u can check method

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

for reason.

2)u don't have to specify concrete core name.U can specify core name using annotation

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

on corresponding solr model.

3)set multicoreSupport = true

According to your sample of classes, they should look like as following:

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: Latest spring-data-solr 3.x.x already support custom query request method,see post issue

qfrank
  • 262
  • 3
  • 14