在使用Solr过程中,有时候为了对数据进行分别管理,我们要创建多个collection以及多个shard来管理索引数据。但是问题随之而来,如何跨collection查询数据?在发现Collection API中的CREATEALIAS之前,我们想过采用程序自己去实现分布式查询路由。最近看Solr官方文档过程中,发现采用CREATEALIAS可以对多个collection创建一个alias。于是尝试能否通过alias实现跨collection查询。

测试环境

  • Solr版本:CDH5.4.4-solr4.10.3
  • 在SolrCloud模式下启动6个Solr实例
  • 采用独立的zookeeper集群

测试过程

1. 创建两个采用相同config,相同schema的Collection,分别命名为c1,c2

采用如下API接口:

http://192.168.11.101:8983/solr/admin/collections?action=CREATE&name=c1&numShards=3&replicationFactor=1&maxShardsPerNode=1&collection.configName=myconf

http://192.168.11.101:8983/solr/admin/collections?action=CREATE&name=c2&numShards=3&replicationFactor=1&maxShardsPerNode=1&collection.configName=myconf

==其中myconf已经通过上传到zookeeper中/solr/configs目录下。==

创建成功后在Web中可以看到如下结果:

image

2. 采用SolrJ向两个Collection插入数据

向c1中插入id从0-19的数据


cloudSolrServer.setDefaultCollection("c1"); ... List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>(); for(int i=0; i<20; i++){ SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", i); doc.addField("title", "abc"+i); docs.add(doc); } try { cloudSolrServer.add(docs); } catch (SolrServerException e) { // TODO Auto-generated catch block e.printStackTrace(); }

向c2中插入id从20-39的数据,代码同上。

3. 分别查询c1和c2数据,可以看到各自的索引数据

截图:略

4. 为c1和c2创建别名cc

http://192.168.11.101:8983/solr/admin/collections?action=CREATEALIAS&name=cc&collections=c1,c2

5. 使用cc作为defaultCollection使用cloudSolrServer去查询


cloudSolrServer.setDefaultCollection("cc"); ... SolrQuery query = new SolrQuery(); query.setQuery("*:*"); query.setStart(0); query.setRows(100); try { QueryResponse response = cloudSolrServer.query(query); SolrDocumentList results = response.getResults(); System.out.println("Total : " + results.size()); for(SolrDocument doc : results){ System.out.println(doc.getFieldValue("title")); } } catch (SolrServerException e) { // TODO Auto-generated catch block e.printStackTrace(); }

查询结果可以看到包含了c1(20条)和c2(条)中所有的数据,共计40条数据。结果如下:

image

总结

以上就是在SolrCloud模式下通过SolrJ的跨collection查询。在使用HTTP API时,我们可以直接指定collection list来进行查询。如下:

http://localhost:8983/solr/collection1/select?q=test&collection=collection1,collection2,collection3

在Solr单实例模式下,通常是通过指定shards参数来指定要查询solr实例,如下:

http://localhost:8983/solr/collection1/select?q=test&shards=10.0.0.1:8983/solr/collection1,10.0.0.2:8983/solr/collection1,10.0.0.3:8983/solr/collection1

其中10.0.0.2:8983/solr/collection1,10.0.0.3:8983/solr/collection1为独立的solr实例。其原理和SolrCloud的跨shards查询是一样的。

参考

https://wiki.apache.org/solr/SolrCloud
https://wiki.apache.org/solr/DistributedSearch

Solr跨Collection查询
Tagged on:     

3 thoughts on “Solr跨Collection查询

  • 2017年4月5日 at 下午3:45
    Permalink

    多谢作者的分享,很受启发。最近正在苦恼公司有好几个collection要怎么整合到一起。准备去试下alias。不过看来在这之前,我需要统一下几个collection的schame,再将id处理一下。 话说,如果c1和c2中有重复的id,不知道会怎么样?报错?

    Reply
    • 2017年4月5日 at 下午3:49
      Permalink

      应该都会返回,因为这个id应该在collection范围内的概念。而通过alias查询,应该是将一个查询请求分布式的请求到对应的collections中,然后将获取的结果合并返回。具体我没有测试过,我觉得应该是这样。

      Reply
      • 2017年4月11日 at 下午5:24
        Permalink

        我去试了下。发现不用处理id,连schame都不用统一。这真是太方便了

        Reply

发表评论

电子邮件地址不会被公开。 必填项已用*标注