同时返回父子数据Elasticsearch关联查询案例分享


声明:本文转载自https://my.oschina.net/bboss/blog/1794165,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

    在《Elasticsearch 父子关系维护和检索案例分享》一文中介绍了Elasticsearch 父子关系维护和检索的基本功能,本文接着上篇文档,分享同时返回父子数据Elasticsearch 关联查询案例。

本文涉及到的技术点:

  1. inner_hits的使用,通过inner_hits来同时返回父表数据和子表数据
  2. 父子双向数据检索及结果绑定和遍历

1.准备工作

参考文档《高性能elasticsearch ORM开发库使用介绍》导入和配置es客户端

2.定义带inner_hits的dsl检索语句

在dsl配置文件-esmapper/indexparentchild.xml中增加两个dsl检索语句:

hasChildSearchReturnParent2ndChildren 演示在按照雇员信息检索公司数据时,同时返回符合条件的公司下面的员工信息

hasParentSearchByCountryReturnParent2ndChildren 演示在按照公司信息检索雇员数据时,同时返回符合条件的雇员对应的公司信息

    <!--以雇员姓名为条件检索公司信息并返回公司雇员信息-->     <property name="hasChildSearchReturnParent2ndChildren">         <![CDATA[             {               "query": {                 "has_child": {                   "type":       "employee",                   "score_mode": "max",                   "query": {                     "match": {                       "name": #[name]                     }                   },                   "inner_hits": {}                 }               }             }         ]]>     </property>     <!--根据公司所在的国家信息检索员工信息,同时返回员工所属的公司信息-->     <property name="hasParentSearchByCountryReturnParent2ndChildren">         <![CDATA[             {               "query": {                 "has_parent": {                   "type": "company",                   "query": {                     "match": {                       "country": #[country]                     }                   },                   "inner_hits": {}                 }               }             }         ]]>     </property>

3.定义检索操作方法

在文件 ParentChildTest.java中增加以下方法

 	/** 	 * 检索公司信息,并返回公司对应的雇员信息(符合检索条件的雇员信息) 	 */ 	public void hasChildSearchReturnParent2ndChildren(){ 		ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml"); 		Map<String,Object> params = new HashMap<String,Object>(); 		params.put("name","Alice Smith");  		try { 			ESInnerHitSerialThreadLocal.setESInnerTypeReferences(Employee.class);//指定inner查询结果对于雇员类型 			ESDatas<Company> escompanys = clientUtil.searchList("company/company/_search","hasChildSearchReturnParent2ndChildren",params,Company.class); 			long totalSize = escompanys.getTotalSize(); 			List<Company> companyList = escompanys.getDatas();//获取符合条件的公司 			//查看公司下面的雇员信息(符合检索条件的雇员信息) 			for (int i = 0; i < companyList.size(); i++) { 				Company company = companyList.get(i); 				List<Employee> employees = ResultUtil.getInnerHits(company.getInnerHits(), "employee"); 				System.out.println(employees.size()); 			} 		} 		finally{ 			ESInnerHitSerialThreadLocal.clean();//清空inner查询结果对于雇员类型 		} 	} 	/** 	 * 通过公司所在国家检索雇员信息,并返回雇员对应的公司信息 	 */ 	public void hasParentSearchByCountryReturnParent2ndChildren(){  		ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml"); 		Map<String,Object> params = new HashMap<String,Object>(); 		params.put("country","UK");  		try { 			ESInnerHitSerialThreadLocal.setESInnerTypeReferences(Company.class);//指定inner查询结果对于公司类型 			ESDatas<Employee> escompanys = clientUtil.searchList("company/employee/_search","hasParentSearchByCountryReturnParent2ndChildren",params,Employee.class); 			List<Employee> employeeList = escompanys.getDatas();//获取符合条件的雇员数据 			long totalSize = escompanys.getTotalSize(); 			//查看每个雇员对应的公司信息 			for(int i = 0;  i < employeeList.size(); i ++) { 				Employee employee = employeeList.get(i); 				List<Company> companies = ResultUtil.getInnerHits(employee.getInnerHits(), "company"); 				System.out.println(companies.size()); 			} 		} 		finally{ 			ESInnerHitSerialThreadLocal.clean();//清空inner查询结果对于公司类型 		} 	}

说明:

1) 通过ESInnerHitSerialThreadLocal指定了inner_hits中需要返回的数据对象类型

ESInnerHitSerialThreadLocal.setESInnerTypeReferences(Employee.class);//指定inner查询结果对于雇员类型
ESInnerHitSerialThreadLocal.setESInnerTypeReferences(Company.class);//指定inner查询结果对于公司类型

使用后需要清除:

ESInnerHitSerialThreadLocal.clean();//清空inner查询结果对于雇员类型

2) employee.getInnerHits()和company.getInnerHits()方法都是从ESBaseData继承的方法,bboss会自动将inner_hits检索到的父子关联数据设置到ESBaseData对象中,可以通过getInnerHits()方法获取到对应的数据;

3) ResultUtil.getInnerHits工具用于获取关联结果集合,方法的第二个参数对应inner_hits检索的类型和名称:

List<Employee> employees = ResultUtil.getInnerHits(company.getInnerHits(), "employee");       

List<Company> companies = ResultUtil.getInnerHits(employee.getInnerHits(), "company");

4.执行测试方法

通过junit,执行新的测试方法

@Test public void testFromJson(){    createIndice();    importFromJsonData();    hasChildSearchByBirthday();    this.hasChildSearchByName();    this.hasChildSearchByMinChild();    this.hasParentSearchByCountry();     this.hasChildSearchReturnParent2ndChildren();//本文对应的方法    this.hasParentSearchByCountryReturnParent2ndChildren();//本文对应的方法 }

5.参考文档

https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-request-inner-hits.html#nested-inner-hits

 

 

本文发表于2018年04月11日 22:38
(c)注:本文转载自https://my.oschina.net/bboss/blog/1794165,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2662 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1