4

I have apache solr with multiple cores e.g. currency, country etc... So using Spring Data Solr I can retrieve information from one core. I have got this XML configuration right now queries against 'currency' core. If I wanted to query against 'country' core how can I set this up?

<!-- Enable Solr repositories and configure repository base package -->
<solr:repositories base-package="com.acme.repository" solr-template-ref="solrCurrencyTemplate"/>

<solr:solr-server id="solrCurrencyServer" url="http://localhost:8983/solr/currency"/>

<bean id="solrCurrencyTemplate" class="org.springframework.data.solr.core.SolrTemplate">
    <constructor-arg ref="solrCurrencyServer" />
</bean>

and have the repository defined as

@Repository
public interface CurrencyRepository extends SolrCrudRepository<Currency, String> {

}

and from my service I can do this

@Override
public List<Currency> getCurrencies() {
    Page<Currency> currencies = (Page<Currency>) currencyRepository.findAll();
    return currencies.getContent();
}

I have also tried using @SolrDocument(solrCoreName = "currency") but this din't work.

@SolrDocument(solrCoreName = "currency")
public class Currency {
    public static final String FIELD_CURRENCY_NAME = "currency_name";
    public static final String FIELD_CURRENCY_CODE = "currency_code";
    public static final String FIELD_DECIMALS = "decimals";

    @Id
    @Field(value = FIELD_CURRENCY_CODE)
    private String currencyCode;

    //currency_name,decimals
    @Field(value = FIELD_CURRENCY_NAME)
    private String currencyName;

    @Field(value = FIELD_DECIMALS)
    private String decimals;

...
...
...
}

I need help on this asap... otherwise I will have to go back to the RestTemplate Solution :-(

Hope someone can help. Thanks GM

user2279337
  • 691
  • 5
  • 13
  • 26

5 Answers5

9

Thought I would share, We spend lot of time recently configuring multiple cores. We did in java, not xml.

As part of spring @configuration add following.

@Bean(name="solrCore1Template")
public SolrTemplate solrCore1Template() throws Exception {
    EmbeddedSolrServer embeddedSolrServer = new EmbeddedSolrServer(getCoreContainer(), "core1");
    return new SolrTemplate(embeddedSolrServer);
}

@Bean(name="solrCore2Template")
public SolrTemplate solrCore2Template() throws Exception {   
    EmbeddedSolrServer embeddedSolrServer = new EmbeddedSolrServer(getCoreContainer(), "core2");
    return new SolrTemplate(embeddedSolrServer);
}

@Bean
@Scope
public CoreContainer getCoreContainer() throws FileNotFoundException{
    String dir = <path_to_solr_home>;
    System.setProperty("solr.solr.home", dir);
    CoreContainer.Initializer initializer = new CoreContainer.Initializer();
    return initializer.initialize();
}

And to use each template use like below in service classes.

@Resource
private SolrTemplate solrCore1Template;

Embedded server can be relaced with HTTP using below code.

HttpSolrServer httpSolrServer = new HttpSolrServer(getSolrURL());
return new SolrTemplate(httpSolrServer, "core1");

Hope this helps. I know it's a very late reply for the question asked.

titogeo
  • 2,156
  • 2
  • 24
  • 41
4

multicore support via namespace config is unfortunately an open issue. You'll need to have a separate SolrTemplate for each core and create repositories manually.

@Autowired 
@Qualifier("solrCurrencyTemplate")
private SolrTemplate solrCurrencyTemplate;

@Autowired
@Qualifier("solrCountryTemplate")
private SolrTemplate solrCountryTemplate;

//...

CurrencyRepository currencyRepo = new SolrRepositoryFactory(this.solrCurrencyTemplate)
  .getRepository(CurrencyRepository.class);

CountryRepository countryRepo = new SolrRepositoryFactory(this.solrCountryTemplate)
  .getRepository(CountryRepository.class);
Matthias
  • 3,582
  • 2
  • 30
  • 41
Christoph Strobl
  • 6,491
  • 25
  • 33
  • 1
    Is the multiple core still not supported? Thanx. – checklist Dec 25 '13 at 08:43
  • Is there any plan for adding support for multiple cores in near future? – Aamir Yaseen Dec 30 '13 at 21:02
  • Yes there are plans for better multicore support. As a first step there's `MulticoreSolrServerFactory` which can be used in `SolrTempate` – Christoph Strobl Jan 02 '14 at 06:59
  • 2
    Spring Data Solr 1.1.0.RC1 offers extended Multicore support via `@EnableSolrRepositories(basePackages = {"org.springframework.data.solr.showcase"}, multicoreSupport=true)` which reads core/collection information from `@SolrDocument` and creates the required `SolrTemplate`s along with the repository. Only thing that has to be present in configuration is a `SolrServer` pointing to solr base path, as collection information will be added. – Christoph Strobl Jan 30 '14 at 14:26
  • 1
    @ChristophStrobl Your way works but how to autowire the propper solrTemplate for a specific collection? I always end with spring exception "no qualified bean found"... Are created solrTemplate beans? Thanks. – ramon_salla Apr 01 '14 at 17:11
  • @ramon_salla the SolrTemplates created by multicoreSupport are not registered in context to avoid NoUniqueBean errors in case a template would be autowired. So just create the Template in your context using the solrServer instance and use that one for custom implementations. – Christoph Strobl Apr 01 '14 at 18:28
  • MultiCore with multirepository is now supported. Refer http://stackoverflow.com/questions/35378648/how-to-configure-spring-data-solr-with-repositories-for-multiple-cores/35379501#35379501 for more details. – Nikhil Sahu Feb 13 '16 at 12:16
2

Spring Data now supports multiple cores with their respective repositories.

The multicoreSupport flag needs to be true in @EnableSolrRepositories annotation and the corresponding document needs to be told what core they belong to. Like:

@SolrDocument(solrCoreName = "currency")
public class Currency
{
    // attributes
}

the other class should be

@SolrDocument(solrCoreName = "country")
public class Country
{
    // attributes
}

The respective repositories should know what pojo they are working with.

public interface CurrencyRepository extends SolrCrudRepository<Currency,String>
{
}

and

public interface CountryRepository extends SolrCrudRepository<Country,String>
{
}

and configuration should be

@Configuration
@EnableSolrRepositories(value = "com.package.name",multicoreSupport = true)
public class SolrConfig
{
    @Bean
    public SolrServer solrServer() throws Exception
    {
        HttpSolrServerFactoryBean f = new HttpSolrServerFactoryBean();
        f.setUrl("http://localhost:8983/solr");
        f.afterPropertiesSet();
        return f.getSolrServer();
    }

    @Bean
    public SolrTemplate solrTemplate(SolrServer solrServer) throws Exception
    {
        return new SolrTemplate(solrServer());
    }
}
yassine yousfi
  • 79
  • 2
  • 11
Nikhil Sahu
  • 2,463
  • 2
  • 32
  • 48
1

With Spring Data Solr 1.1.0.RC1 multiple cores works as described by Christoph Strobl with @EnableSolrRepositories. It works also with an XML configuration by set multicore-support="true".

<solr:repositories base-package="your.solr.repo.package" repository-impl-postfix="Impl" multicore-support="true"/>

<solr:solr-server id="solrServer" url="${solr.server.base.connection.url}" />

<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
    <constructor-arg index="0" ref="solrServer" />
</bean>
nydi
  • 11
  • 2
1
<solr:solr-server id="solrServer" timeout="1000" maxConnections="1000" url="${solr.server.1},${solr.server.2}"/>

<bean id="solrServerFactory" class="org.springframework.data.solr.server.support.MulticoreSolrServerFactory">
    <constructor-arg ref="solrServer" />
    <constructor-arg name="cores">
        <list>
            <value>${solr.index.customer}</value>
            <value>${solr.index.task}</value>
        </list>
    </constructor-arg>
</bean>

<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
    <constructor-arg ref="solrServerFactory" />
</bean>

<solr:repositories base-package="com.deve.pig.solr" multicore-support="true" solr-template-ref="solrTemplate" />