`

Elasticsearch 父子关系维护和检索案例分享

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

本文涉及技术点:
  • 1.删除和创建公司/雇员父子关系的索引表
  • 2.bulk批量导入json格式数据
  • 3.ormapping方式bulk批量导入数据
  • 4.采用@ESId指定文档_id
  • 5.采用@ESParentId制定子文档的parent信息
  • 6.基本的has_child和has_parent公司/雇员父子关系检索


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

2.定义dsl文档
建立dsl配置文件-esmapper/indexparentchild.xml
<properties>
    <!--
    本案例适用于es 2.x,5.x
    创建包含员工类型和公司类型的公司索引表
    -->
    <property name="createCompanyEmployeeIndice">
        <![CDATA[{
            "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"
                        }
                    }
                }

              }
        }]]>
    </property>
    <!--
    导入公司信息:
    -->
    <property name="bulkImportCompanyData">
        <![CDATA[
            { "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" }
        ]]>
    </property>
    <!--
   导入雇员信息:
   -->
    <property name="bulkImportEmployeeData">
        <![CDATA[
            { "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}
        ]]>
    </property>
    <!--出生日期为条件检索公司信息-->
    <property name="hasChildSearchByBirthday">
        <![CDATA[
            {
              "query": {
                "has_child": {
                  "type": "employee",
                  "query": {
                    "range": {
                      "birthday": {
                        "gte": #[birthday]
                      }
                    }
                  }
                }
              }
            }
        ]]>
    </property>
    <!--姓名为条件检索公司信息-->
    <property name="hasChildSearchByName">
        <![CDATA[
            {
              "query": {
                "has_child": {
                  "type":       "employee",
                  "score_mode": "max",
                  "query": {
                    "match": {
                      "name": #[name]
                    }
                  }
                }
              }
            }
        ]]>
    </property>
    <!--最小员工数为条件检索公司信息-->
    <property name="hasChildSearchByMinChild">
        <![CDATA[
            {
                "query": {
                    "has_child": {
                      "type":  "employee",
                      "min_children": #[min_children],
                      "query": {
                        "match_all": {}
                      }
                    }
                }
            }
        ]]>
    </property>

    <!--检索员工信息-->
    <property name="hasParentSearchByCountry">
        <![CDATA[
            {
              "query": {
                "has_parent": {
                  "type": "company",
                  "query": {
                    "match": {
                      "country": #[country]
                    }
                  }
                }
              }
            }
        ]]>
    </property>
</properties>

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<Company> companies = buildCompanies();
		clientUtil.addDocuments("company","company",companies,"refresh");

		//导入雇员数据,并且实时刷新,测试需要,实际环境不要带refresh
		List<Employee> employees = buildEmployees();
		clientUtil.addDocuments("company","employee",employees,"refresh");
	}

List<Company>和List<Employee>列表分别对应需要批量导入的公司数据和雇员数据。需要特别说明的是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<String,Object> params = new HashMap<String,Object>();
		params.put("birthday","1980-01-01");
		ESDatas<Company> escompanys = clientUtil.searchList("company/company/_search","hasChildSearchByBirthday",params,Company.class);
		List<Company> companyList = escompanys.getDatas();//获取符合条件的公司
		long totalSize = escompanys.getTotalSize();
	}

	/**
	 * 通过雇员姓名检索公司信息
	 */
	public void hasChildSearchByName(){

		ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("name","Alice Smith");
		ESDatas<Company> escompanys = clientUtil.searchList("company/company/_search","hasChildSearchByName",params,Company.class);
		List<Company> companyList = escompanys.getDatas();//获取符合条件的公司
		long totalSize = escompanys.getTotalSize();

	}
	/**
	 * 通过雇员数量检索公司信息
	 */
	public void hasChildSearchByMinChild(){

		ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("min_children",2);
		ESDatas<Company> escompanys = clientUtil.searchList("company/company/_search","hasChildSearchByMinChild",params,Company.class);
		List<Company> companyList = escompanys.getDatas();//获取符合条件的公司
		long totalSize = escompanys.getTotalSize();

	}
	/**
	 * 通过公司所在国家检索雇员信息
	 */
	public void hasParentSearchByCountry(){

		ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/indexparentchild.xml");
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("country","UK");
		ESDatas<Employee> escompanys = clientUtil.searchList("company/employee/_search","hasParentSearchByCountry",params,Employee.class);
		List<Employee> companyList = escompanys.getDatas();//获取符合条件的公司
		long totalSize = escompanys.getTotalSize();

	}

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

   
@Test
	public void test(){
		createIndice();
		importData();
		hasChildSearchByBirthday();
		this.hasChildSearchByName();
		this.hasChildSearchByMinChild();
		this.hasParentSearchByCountry();
	}

4.参考文档
https://blog.csdn.net/napoay/article/details/52032931

https://gitee.com/bboss/elasticsearchdemo/blob/master/src/test/java/org/frameworkset/elasticsearch/parentchild/ParentChildTest.java

https://gitee.com/bboss/elasticsearchdemo/blob/master/src/test/resources/esmapper/indexparentchild.xml

测试用例对应的工程

https://gitee.com/bboss/elasticsearchdemo

5 开发交流
elasticsearch技术交流群:166471282

elasticsearch微信公众号:bbossgroups
1
0
分享到:
评论

相关推荐

    ElasticSearch分享ppt40页+.pptx

    总的来说,ElasticSearch因其强大的搜索和分析能力、分布式特性及广泛的集成支持,成为Java学习者和技术分享者的重要工具。它不仅适用于日志分析、实时搜索,还广泛应用于监控、物联网、内容管理系统等多个领域。...

    Elasticsearch in Action 全文检索

    Elasticsearch in Action 全文检索Elasticsearch in Action 全文检索Elasticsearch in Action 全文检索Elasticsearch in Action 全文检索Elasticsearch in Action 全文检索Elasticsearch in Action 全文检索

    基于分布式ElasticSearch的海量遥感影像检索方法研究.pdf

    该研究的核心价值在于提供了一种基于分布式ElasticSearch技术的遥感影像检索方法,通过高效地映射和存储遥感影像元数据,能够快速且有效地对海量遥感影像进行检索。这不仅为遥感影像检索技术的发展提供了新的思路,...

    Elasticsearch全文检索

    在` ESDemo `项目中,你可以找到上述操作的具体实现代码,这将帮助你更深入地理解如何在Spring Boot应用中整合和使用Elasticsearch进行全文检索。通过学习和实践,你将能够熟练地运用Elasticsearch来解决大数据的...

    人工智能-项目实践-检索引擎-基于ElasticSearch的海量文本检索系统

    基于ElasticSearch的海量文本检索系统 基于ElasticSearch的海量文本检索系统,目前支持txt, doc, docx, pdf, ppt格式文本上传及全文查询,本项目作为本人的毕业设计

    springboot+es实现对word,pdf,txt等文件的非结构化数据全文内容检索

    总的来说,通过Spring Boot、Elasticsearch和Kibana的组合,我们可以构建一个高效的非结构化数据全文检索系统,覆盖多种文件格式,满足复杂的信息检索需求。这个系统的应用范围广泛,包括但不限于文档管理、知识图谱...

    ElasticSearch和activiti案例

    **Elasticsearch与Activiti深度整合案例** 在现代企业信息化建设中,Elasticsearch和Activiti作为两个重要的技术组件,分别扮演着数据搜索与流程管理的重要角色。Elasticsearch是一款强大的分布式搜索引擎,以其...

    人工智能-项目实践-检索引擎-基于Java8的SSM+Elasticsearch全文检索的个人博客系统

    在这个名为“人工智能-项目实践-检索引擎-基于Java8的SSM+Elasticsearch全文检索的个人博客系统”的项目中,开发者构建了一个集成了人工智能技术的个人博客系统,它利用了现代搜索引擎技术,特别是Elasticsearch,来...

    Elasticsearch官方提供数据案例account.json

    在这个案例中,"account.json"是Elasticsearch官方提供的一个示例数据集,旨在帮助用户了解如何在Elasticsearch中处理和查询JSON格式的数据。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人...

    elasticsearch 8.11.3 windows安装包

    Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。Logstash 和 Beats 有助于收集、聚合和丰富您的数据并将其存储在 Elasticsearch 中。Kibana 使您能够以交互方式探索、可视化和分享对数据的见解,...

    ElasticSearch 学习案例

    首先,让我们来看一下如何在 Elasticsearch 中插入和检索数据。这里展示的是使用 Bulk API 插入测试帖子数据。每个帖子包含 `articleID`、`userID`、`hidden` 和 `postDate` 四个字段。由于 Elasticsearch 支持 JSON...

    Elasticsearch实现检索词自动补全(检索词补全,自动纠错,拼音补全,繁简转换) 包含demo

    在实际应用中,用户输入的检索词往往可能存在拼写错误、不完整或者使用了同义词等情况,为了提高用户体验和搜索准确性,Elasticsearch 提供了多种功能来支持检索词的自动补全、自动纠错、拼音补全以及繁简转换。...

    Elasticsearch经典案例:日志分析和监控系统.zip

    Elasticsearch经典案例:日志分析和监控系统.zip Elasticsearch经典案例:日志分析和监控系统.zip Elasticsearch经典案例:日志分析和监控系统.zip Elasticsearch经典案例:日志分析和监控系统.zip Elasticsearch...

    ES查询客户端,elasticsearch可视化工具 elasticsearch查询客户端

    Elasticsearch(简称ES)是一款强大的开源搜索引擎,广泛应用于数据检索、分析和管理。作为分布式、RESTful风格的搜索和数据分析引擎,Elasticsearch能够提供实时、高可用性以及可扩展的搜索功能。在进行日常的数据...

    基于Java8的SSM+Elasticsearch全文检索的个人博客系统.zip

    在博客系统中,Elasticsearch可以存储和索引博客文章内容,以便快速地进行关键词搜索。 整合SSM与Elasticsearch的关键步骤包括: 1. **配置Elasticsearch**:在项目中引入Elasticsearch的Java客户端依赖,并配置...

    JAVA实现ElasticSearch的简单实例

    1. **Elasticsearch基础**:Elasticsearch(ES)是一个开源的、分布式全文搜索引擎,它提供了实时数据分析的能力,广泛用于日志分析、监控、搜索应用等领域。其核心特性包括分布式、RESTful接口、实时性、可扩展性和...

    十分钟学会使用 Elasticsearch 优雅搭建自己的搜索系统.pdf

    Elasticsearch 是一个开源的高度可扩展的全文搜索和分析引擎,拥有查询近实时的超强性能。 大名鼎鼎的Lucene 搜索引擎被广泛用于搜索领域,但是操作复杂繁琐,总是让开发者敬而远之。而 Elasticsearch将 Lucene 作为...

    Elastic Search搭建使用教程.pdf(内含ElasticSearch教程权威指南)

    这些应用案例都展示了Elasticsearch在全文搜索、结构化搜索和数据分析方面的强大能力。 Elasticsearch的实时特性意味着它能够在数据被索引后,几乎即时地提供搜索结果。这使得Elasticsearch非常适合于需要快速响应...

    (狂神)ElasticSearch快速入门笔记,ElasticSearch基本操作以及爬虫(Java-ES仿京东实战)

    好记性不如烂笔头哦~,ElasticSearch,简称es,es是一个开源的高拓展的分布式全文搜索引擎它可以近乎实时的存储、检索数据;本身拓展性很好,可以拓展到上百台服务器,处理PB级别的数据。es也是用Java开发并使用...

Global site tag (gtag.js) - Google Analytics