本文涉及到的技术点:
- inner_hits的使用,通过inner_hits来同时返回父表数据和子表数据
- 父子双向数据检索及结果绑定和遍历
1.准备工作
参考文档《 高性能elasticsearch ORM开发库使用介绍》导入和配置es客户端
2.定义带inner_hits的dsl检索语句
在dsl配置文件-esmapper/indexparentchild.xml中增加两个dsl检索语句:
hasChildSearchReturnParent2ndChildren 演示在按照雇员信息检索公司数据时,同时返回符合条件的公司下面的员工信息
hasParentSearchByCountryReturnParent2ndChildren 演示在按照公司信息检索雇员数据时,同时返回符合条件的雇员对应的公司信息
3.定义检索操作方法
在文件 ParentChildTest.java中增加以下方法
/** * 检索公司信息,并返回公司对应的雇员信息(符合检索条件的雇员信息) */ public void hasChildSearchReturnParent2ndChildren(){ ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml"); Mapparams = new HashMap (); params.put("name","Alice Smith"); try { ESInnerHitSerialThreadLocal.setESInnerTypeReferences(Employee.class);//指定inner查询结果对于雇员类型 ESDatas escompanys = clientUtil.searchList("company/company/_search","hasChildSearchReturnParent2ndChildren",params,Company.class); long totalSize = escompanys.getTotalSize(); List companyList = escompanys.getDatas();//获取符合条件的公司 //查看公司下面的雇员信息(符合检索条件的雇员信息) for (int i = 0; i < companyList.size(); i++) { Company company = companyList.get(i); List 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 params = new HashMap (); params.put("country","UK"); try { ESInnerHitSerialThreadLocal.setESInnerTypeReferences(Company.class);//指定inner查询结果对于公司类型 ESDatas escompanys = clientUtil.searchList("company/employee/_search","hasParentSearchByCountryReturnParent2ndChildren",params,Employee.class); List employeeList = escompanys.getDatas();//获取符合条件的雇员数据 long totalSize = escompanys.getTotalSize(); //查看每个雇员对应的公司信息 for(int i = 0; i < employeeList.size(); i ++) { Employee employee = employeeList.get(i); List 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检索的类型和名称:
Listemployees = ResultUtil.getInnerHits(company.getInnerHits(), "employee"); List 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
6.开发交流
elasticsearch技术交流群:166471282
elasticsearch微信公众号:bbossgroups