`
qindongliang1922
  • 浏览: 2188609 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117663
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:126070
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:60024
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71399
社区版块
存档分类
最新评论

如何使用solr的join

    博客分类:
  • Solr
阅读更多
对于用惯数据库的我们,多表进行join连接,是非常常见的一个需求,但是在我们的索引中,对join的支持,却不是很完美,当然这并不是由于我们的Lucene或Solr不够强大,而是全文检索与数据库的定位不是在同一个目标上,全文检索,主要定位在搜索引擎上,通常是对一个大的索引进行高效检索,而数据库则是定位在结构化数据的存储于与检索,检索功能比较薄弱,那我们的索引是不是就不支持join了,实事并非如此,Lucene里面支持join操作,这种join定位在同一份索引里,而Solr作为Lucene的扩展,又提供了两core join的功能,下面散仙给出一个例子,尽量简单,清晰的描述出如何使用它们和理解它们的工作方式。



散仙,有2个core,分别是collection1,和collection2,里面的数据分别是:
collection1:总共有3条数据
collection1:schema 都是字符串string ;  有id,name两个字段 ;
collection1: {1, Apple}, {2, Samsung}, {3, HTC}

collection2:总共有5条数据
collection2:schema 都是字符串string ;有id,name,brand_id 两个字段;
collection2: {1, iPhone, 1}, {2, iPad, 1}, {3, Galaxy S3, 2}, {4, Galaxy Note, 2}, {5, One X, 3}


下面,先来看下单core的join,以collection2作为例子,测试代码如下:

/***
 * join测试
 * 
 * 
 * ***/
public static void joinquery2()throws Exception{
	SolrServer server1=new HttpSolrServer("http://localhost:9003/solr/collection2");
	SolrQuery sq=new SolrQuery();
	//sq.set("fl", "id,name");//过滤只需要返回的字段
	 sq.set("q", "{!join from=id  to=brand_id }brand_id:*");
	QueryResponse qr=server1.query(sq, METHOD.POST);
	 SolrDocumentList list=qr.getResults();
	System.out.println("命中结果集:"+qr.getResults().size());
	for(SolrDocument s:list){
		System.out.println(s.toString());
	}
}

运行结果如下:
五月 14, 2014 9:03:58 下午 org.apache.solr.client.solrj.impl.HttpClientUtil createClient
INFO: Creating new http client, config:maxConnections=128&maxConnectionsPerHost=32&followRedirects=false
命中结果集:5
SolrDocument{id=1, name=iPhone, brand_id=1, _version_=1468079557386960896}
SolrDocument{id=2, name=iPad, brand_id=1, _version_=1468079557408980992}
SolrDocument{id=3, name=Galaxy, brand_id=2, _version_=1468079557412126720}
SolrDocument{id=4, name=Galaxy Note, brand_id=2, _version_=1468079557416321024}
SolrDocument{id=5, name=One X, brand_id=3, _version_=1468079557420515328}

改变,条件后,再测:
/***
 * join测试
 * 
 * 
 * ***/
public static void joinquery2()throws Exception{
	SolrServer server1=new HttpSolrServer("http://localhost:9003/solr/collection2");
	SolrQuery sq=new SolrQuery();
	//sq.set("fl", "id,name");//过滤只需要返回的字段
	 sq.set("q", "{!join from=id  to=brand_id }brand_id:2");
	QueryResponse qr=server1.query(sq, METHOD.POST);
	 SolrDocumentList list=qr.getResults();
	System.out.println("命中结果集:"+qr.getResults().size());
	for(SolrDocument s:list){
		System.out.println(s.toString());
	}
}


运行结果如下:
五月 14, 2014 9:10:04 下午 org.apache.solr.client.solrj.impl.HttpClientUtil createClient
INFO: Creating new http client, config:maxConnections=128&maxConnectionsPerHost=32&followRedirects=false
命中结果集:1
SolrDocument{id=5, name=One X, brand_id=3, _version_=1468079557420515328}

分析运行原理,类似sql中的写法:

SELECT *
FROM collection1
WHERE brand_id IN (SELECT id FROM collection1 where brand_id = * )

第一步,先执行子查询SELECT id FROM collection1 where brand_id = *
会返回所有的id分别是,1,2,3,4,5
第二步,执行主查询就是

SELECT *
FROM collection1
WHERE brand_id  in (1,2,3,4,5)

而brand_id去重完之后,就只有1,2,3了,所以转换成如下查询:
SELECT *
FROM collection1
WHERE  brand_id(1,2,3)  in (1,2,3,4,5)

取并集后结果,就会命中brand_id=1,2,3的文档,所以就命中了所有的文档


再来分析下,第二个查询,指定查询id的join:
第一步,先执行子查询SELECT id FROM collection1 where brand_id = 2
会返回所有的id分别是,3,4,
第二步,执行主查询就是

SELECT *
FROM collection1
WHERE brand_id  in (3,4)

而brand_id去重完之后,就只有1,2,3了,所以转换成如下查询:
SELECT *
FROM collection1
WHERE  brand_id(1,2,3)  in  brand_id(3,4)

取并集后的结果,就会命中brand_id=3的文档了,所以就会返回ID为5的文档;




下面,来测下,两个core的join,代码如下:
/***
 * join测试
 * 
 * 
 * ***/
public static void joinquery2()throws Exception{
	SolrServer server1=new HttpSolrServer("http://localhost:9003/solr/collection1");
	SolrQuery sq=new SolrQuery();
	//sq.set("fl", "id,name");//过滤只需要返回的字段
	sq.set("q", "{!join from=brand_id to=id fromIndex=collection2}name:iPad");
	QueryResponse qr=server1.query(sq, METHOD.POST);
	 SolrDocumentList list=qr.getResults();
	System.out.println("命中结果集:"+qr.getResults().size());
	for(SolrDocument s:list){
		System.out.println(s.toString());
	}
}

结果如下:
五月 14, 2014 9:30:41 下午 org.apache.solr.client.solrj.impl.HttpClientUtil createClient
INFO: Creating new http client, config:maxConnections=128&maxConnectionsPerHost=32&followRedirects=false
命中结果集:1
SolrDocument{id=1, name=Apple, _version_=1468079556974870528}

分析类似如下SQL:

SELECT b.* FROM  collection1 b
       INNER JOIN collection2 p ON b.id=p.brand_id
       WHERE p.name="iPad";

注意collection名的先后顺序,如上solrj里面的执行,跟上面的sql的运行规则是一样的,所以我们最终的结果里,会返回,如果我们的条件是下面的相反组合:



public static void joinquery()throws Exception{
	SolrServer server1=new HttpSolrServer("http://localhost:9003/solr/collection2");
	SolrQuery sq=new SolrQuery();
	 sq.set("q", "{!join from=id to=brand_id fromIndex=collection1}id:1");
	QueryResponse qr=server1.query(sq, METHOD.POST);
	 SolrDocumentList list=qr.getResults();
	System.out.println("命中结果集:"+qr.getResults().size());
	for(SolrDocument s:list){
		//s.toString();
		System.out.println(s.toString());
	}


则运行结果如下所示:
五月 14, 2014 9:43:46 下午 org.apache.solr.client.solrj.impl.HttpClientUtil createClient
INFO: Creating new http client, config:maxConnections=128&maxConnectionsPerHost=32&followRedirects=false
命中结果集:2
SolrDocument{id=1, name=iPhone, brand_id=1, _version_=1468079557386960896}
SolrDocument{id=2, name=iPad, brand_id=1, _version_=1468079557408980992}

原理,依旧与如上的sql一样。只不过位置相反,调整了:

SELECT b.* FROM  collection2 b
       INNER JOIN collection1 p ON b.id=p.brand_id
       WHERE b.id=1;






分享到:
评论

相关推荐

    基于Solr的多表join查询加速方法

    - **查询设计**:通过调整查询语句的结构,如使用“exists”查询或“join”查询,以适应Solr的查询机制,提升性能。 - **硬件和架构优化**:例如,增加Solr服务器的内存,使用SSD硬盘提升I/O速度,或者采用更高效的...

    java进阶Solr从基础到实战

    视频详细讲解,需要的小伙伴自行网盘下载,链接见附件,...2. Solr Join查询 3. 相关度排序 4.Solr缓存 5.Spring Data Solr 章节五:综合案例,电商网站搜索页面 1.关键字搜索 2.搜索面板展示 3.分页 4.排序 5.高亮

    使用java实现solr-7.1.0的api和solr最新支持的sql查询

    在本篇文章中,我们将深入探讨如何使用Java API来与Solr 7.1.0进行交互,并了解Solr最新支持的SQL查询功能。 首先,让我们来讨论如何通过Java API与Solr 7.1.0进行通信。Solr提供了一个名为SolrJ的客户端库,它允许...

    solr基础知识介绍

    Solr支持实时获取文档的最新版本,原子更新文档,支持多层Facet,并且提供了基于关联度的Pseudo-Join操作。Solr还具备Web管理界面,并支持SolrCloud。 Solr的术语部分涉及到了多个与Solr操作相关的概念,例如Auto-...

    solr搜索引擎支持分页

    - 使用`block join`技术,对于具有父子关系的数据,可以提高分页查询效率。 5. 跳跃分页(Deep Paging): 当数据量巨大时,传统的分页方法可能会遇到性能问题,因为每次请求都需要计算总结果数。Solr提供了一种...

    solr在tomcat下的搭建和配置数据库

    LEFT JOIN ic_mcht tt ON (r.MCHT_ID = tt.MCHT_ID)" /> ``` 这里通过`data-config.xml`文件配置了Solr的数据源连接以及SQL查询语句,使得Solr能够从数据库中读取数据并索引。 **总结** 以上步骤详细介绍了...

    lucene-5.3.0+solr-5.3.0 jar包和文档示例

    Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。...

    大型SpringMVC,Mybatis,Redis,Solr,Nginx,SSM分布式电商项目视频教程

    ### 大型SpringMVC、Mybatis、Redis、Solr、Nginx、SSM分布式电商项目视频教程知识点概述 #### 一、SpringMVC框架介绍与应用 **SpringMVC**是Spring框架的一个模块,它实现了MVC设计模式,主要用于构建Web应用程序...

    python 动态迁移solr数据过程解析

    在本文中,我们将探讨如何使用Python进行动态迁移Solr数据的过程。Solr是一个流行的开源搜索引擎,它提供了全文搜索、高级分析功能以及分布式搜索能力。当面临将一个Solr集合中的数据迁移到另一个集合的需求时,我们...

    solr_client_sql_api:solr sql客户端封装

    例如,复杂的JOIN操作和某些特定的SQL函数可能不被支持,因为这些特性在Solr的设计中并未考虑。因此,在使用时,需要根据Solr的特性调整查询语句。 在实际开发中,Solr Client SQL API的使用不仅可以简化代码,提高...

    在Python的gevent框架下执行异步的Solr查询的教程

    5. 使用gevent进行Solr异步查询:通过使用gevent的spawn方法,可以创建一个任务来执行Solr查询。然后,使用gevent.joinall()方法可以等待所有异步任务完成。这种做法可以实现并行执行多个Solr查询,而不必等待每个...

    多线程并发

    如果不需要等待,可以使用 `detach()` 让线程独立运行,但需注意,未被 `join()` 的线程在其执行完毕后不会自动销毁,可能导致内存泄漏。 4. **线程局部存储**:使用 `std::thread_local` 关键字,可以为每个线程...

    大数据各类性能调优

    - **SparkSQL join优化**: 使用Broadcast join或Sort merge join。 - **优化数据倾斜场景下的SparkSQL性能**: 通过Repartition或Coalesce调整数据分布。 - **优化小文件场景下的SparkSQL性能**: 合并小文件。 - ...

    rails _sunspot 学习笔记

    ### Sunspot 安装与使用指南 #### 一、Sunspot简介 Sunspot 是一个用于 Ruby on Rails 的灵活且强大的全文检索框架。它基于 Solr 和 Lucene 构建,可以方便地集成到 Rails 应用中,为用户提供高效的搜索功能。 ##...

    3-9+impala打造交互查询系统.pdf

    10. Join策略:支持多种JOIN类型,如平行JOIN、广播JOIN和分区JOIN。 11. 分区与统计信息:对数据分区进行优化,通过计算统计信息提升查询性能。 12. 支持多种存储系统:除了HDFS,还兼容Amazon S3、Azure Data Lake...

    百家精华面试题.doc

    1. **搜索引擎实现**:面试中提到的搜索实现主要涉及两种技术——Solr和Elasticsearch(ES)。Solr是一款强大的全文搜索引擎,适用于实时更新大数据且支持XML、JSON等多种数据类型。而Elasticsearch是基于HTTP和JSON...

    华为大数据认证HCIP-Big Data Developer H13-723大数据题库

    6. FusionInsightHD系统中Solr资源权限使用:Solr是一个基于Lucene的搜索服务器。在FusionInsightHD系统中,Solr用户组用户可以创建配置集和Collection,但不是只有Solradmin角色和Collection创建者可以删除...

    lucene高级应用

    5. Join操作:虽然Lucene本身不支持JOIN,但通过DocValues或ExternalFileSorter等技术,可以实现跨文档的相关联查询。 四、分布式搜索 1. Solr或Elasticsearch:这两个基于Lucene的高级框架提供了分布式搜索能力,...

    百度持续交付项目组面试题

    **MySQL查询联接方式**包括内联接(INNER JOIN)、左联接(LEFT JOIN)、右联接(RIGHT JOIN)和全外联接(FULL OUTER JOIN)。 - **INNER JOIN**:返回两个表中联接字段相等的行。 - **LEFT JOIN**:返回左表的...

    flora:灵活的开放式休息区Api

    当前实现:MySQL,MongoDB,Elasticsearch,Solr / Lucene 组合多个数据源:甚至基于行-“ API-side-JOIN” 高度优化的数据库查询:内部SQL解析器可删除未选择的字段,从而删除未引用的LEFT JOIN 语言环境:参数化...

Global site tag (gtag.js) - Google Analytics