当前位置:   article > 正文

elasticsearch的父子_Elasticsearch 父子关系维护和检索案例分享

elasticsearch 创建父子索引

Elasticsearch 父子关系维护和检索案例分享,展示has_child和has_parent的基本用法。

本案例针对elasticsearch 5.x进行父子关系进行介绍,6.x版本通过join type来实现父子关系检索,参考文档后面提供的demo。

本文涉及技术点:

1.删除和创建公司/雇员父子关系的索引表

2.bulk批量导入json格式数据

3.ormapping方式bulk批量导入数据

4.采用@ESId指定文档_id

5.采用@ESParentId制定子文档的parent信息

6.基本的has_child和has_parent公司/雇员父子关系检索

1.准备工作

2.定义dsl文档

建立dsl配置文件-esmapper/indexparentchild.xml

"settings": {

"number_of_shards": 6,

"index.refresh_interval": "5s"

},

"mappings": {

"company": { ##公司

"properties": {

"name": {

"type": "text",

"fields": { ##dsl注释 定义精确查找的内部keyword字段

"keyword": {

"type": "keyword"

}

}

},

"city": {

"type": "text",

"fields": { ##dsl注释 定义精确查找的内部keyword字段

"keyword": {

"type": "keyword"

}

}

},

"country": {

"type": "text",

"fields": { ##dsl注释 定义精确查找的内部keyword字段

"keyword": {

"type": "keyword"

}

}

},

"companyId": {

"type": "keyword"

}

}

},

"employee":

{ ##雇员

"_parent": {##定义雇员和公司父子关联关系

"type": "company"

},

"_routing": {

"required": false

},

"properties": {

"name": {

"type": "text",

"fields": { ##dsl注释 定义精确查找的内部keyword字段

"keyword": {

"type": "keyword"

}

}

},

"birthday": {

"type": "date",

"format":"yyyy-MM-dd||epoch_millis"

},

"hobby": {

"type": "text",

"fields": { ##dsl注释 定义精确查找的内部keyword字段

"keyword": {

"type": "keyword"

}

}

},

"companyId": {

"type": "keyword"

},

"employId": {

"type": "keyword"

}

}

}

}

}]]>

{ "index": { "_id": "london" }}

{ "name": "London Westminster", "city": "London", "country": "UK" ,"companyId":"london"}

{ "index": { "_id": "liverpool" }}

{ "name": "Liverpool Central", "city": "Liverpool", "country": "UK" ,"companyId":"liverpool"}

{ "index": { "_id": "paris" }}

{ "name": "Champs Élysées", "city": "Paris", "country": "France","companyId":"paris" }

]]>

{ "index": { "_id": 1, "parent": "london" }}

{ "name": "Alice Smith", "birthday": "1970-10-24", "hobby": "hiking" ,"companyId":"london","employeeId":1 }

{ "index": { "_id": 2, "parent": "london" }}

{ "name": "Mark Thomas", "birthday": "1982-05-16", "hobby": "diving" ,"companyId":"london","employeeId":2}

{ "index": { "_id": 3, "parent": "liverpool" }}

{ "name": "Barry Smith", "birthday": "1979-04-01", "hobby": "hiking" ,"companyId":"liverpool","employeeId":3}

{ "index": { "_id": 4, "parent": "paris" }}

{ "name": "Adrien Grand", "birthday": "1987-05-11", "hobby": "horses" ,"companyId":"paris","employeeId":4}

{ "index": { "_id": 5, "parent": "paris" }}

{ "name": "Adrien Green", "birthday": "1977-05-12", "hobby": "dancing" ,"companyId":"paris","employeeId":5}

]]>

{

"query": {

"has_child": {

"type": "employee",

"query": {

"range": {

"birthday": {

"gte": #[birthday]

}

}

}

}

}

}

]]>

{

"query": {

"has_child": {

"type": "employee",

"score_mode": "max",

"query": {

"match": {

"name": #[name]

}

}

}

}

}

]]>

{

"query": {

"has_child": {

"type": "employee",

"min_children": #[min_children],

"query": {

"match_all": {}

}

}

}

}

]]>

{

"query": {

"has_parent": {

"type": "company",

"query": {

"match": {

"country": #[country]

}

}

}

}

}

]]>

3.实现has_child和has_parent检索

首先创建带公司和雇员关系的索引结构

public void createIndice(){

ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");

try {

//删除mapping

clientUtil.dropIndice("company");

} catch (ElasticSearchException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//创建mapping

clientUtil.createIndiceMapping("company","createCompanyEmployeeIndice");

}

然后通过bulk导入测试需要的公司和雇员数据,本案例通过加载配置文件中的dsl json data导入公司和雇员数据:

public void importData(){

ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");

//导入公司数据,并且实时刷新,测试需要,实际环境不要带refresh

clientUtil.executeHttp("company/company/_bulk?refresh","bulkImportCompanyData",ClientUtil.HTTP_POST);

//导入雇员数据,并且实时刷新,测试需要,实际环境不要带refresh

clientUtil.executeHttp("company/employee/_bulk?refresh","bulkImportEmployeeData",ClientUtil.HTTP_POST);

}

如果需要根据List集合批量导入测试数据,则参考以下方法:

/**

* 通过List集合导入雇员和公司数据

*/

public void importDataFromBeans() {

ClientInterface clientUtil = ElasticSearchHelper.getRestClientUtil();

//导入公司数据,并且实时刷新,测试需要,实际环境不要带refresh

List companies = buildCompanies();

clientUtil.addDocuments("company","company",companies,"refresh");

//导入雇员数据,并且实时刷新,测试需要,实际环境不要带refresh

List employees = buildEmployees();

clientUtil.addDocuments("company","employee",employees,"refresh");

}

List和List列表分别对应需要批量导入的公司数据和雇员数据。需要特别说明的是Company和Employee这两个对象采用了注解@ESId来标注文档_id属性,采用@ESParentId属性来标注雇员和公司的关联属性:

public class Company extends ESBaseData {

private String name;

/**

* 将companyId作为索引_id的值

*/

@ESId

private String companyId;

。。。。。。

public class Employee extends ESBaseData {

/**

* 通过ESId注解将employeeId指定为雇员的文档_id

*/

@ESId

private int employeeId;

/**

* 通过ESParentId注解将companyId指定为雇员的parent属性,对应Company中的文档_id的值

*/

@ESParentId

private String companyId;

接下来实现has_child和has_parent检索功能

/**

* 通过雇员生日检索公司信息

*/

public void hasChildSearchByBirthday(){

ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");

Map params = new HashMap();

params.put("birthday","1980-01-01");

ESDatas escompanys = clientUtil.searchList("company/company/_search","hasChildSearchByBirthday",params,Company.class);

List companyList = escompanys.getDatas();//获取符合条件的公司

long totalSize = escompanys.getTotalSize();

}

/**

* 通过雇员姓名检索公司信息

*/

public void hasChildSearchByName(){

ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");

Map params = new HashMap();

params.put("name","Alice Smith");

ESDatas escompanys = clientUtil.searchList("company/company/_search","hasChildSearchByName",params,Company.class);

List companyList = escompanys.getDatas();//获取符合条件的公司

long totalSize = escompanys.getTotalSize();

}

/**

* 通过雇员数量检索公司信息

*/

public void hasChildSearchByMinChild(){

ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");

Map params = new HashMap();

params.put("min_children",2);

ESDatas escompanys = clientUtil.searchList("company/company/_search","hasChildSearchByMinChild",params,Company.class);

List companyList = escompanys.getDatas();//获取符合条件的公司

long totalSize = escompanys.getTotalSize();

}

/**

* 通过公司所在国家检索雇员信息

*/

public void hasParentSearchByCountry(){

ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");

Map params = new HashMap();

params.put("country","UK");

ESDatas escompanys = clientUtil.searchList("company/employee/_search","hasParentSearchByCountry",params,Employee.class);

List companyList = escompanys.getDatas();//获取符合条件的公司

long totalSize = escompanys.getTotalSize();

}

通过junit测试用例执行上述功能

@Test

public void test(){

createIndice();

importData();

hasChildSearchByBirthday();

this.hasChildSearchByName();

this.hasChildSearchByMinChild();

this.hasParentSearchByCountry();

}

4.参考文档

测试用例对应的工程

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/456705
推荐阅读
相关标签
  

闽ICP备14008679号