• es学习笔记


    1.es介绍

    Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsearch 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。
    Elasticsearch是与名为Logstash的数据收集和日志解析引擎以及名为Kibana的分析和可视化平台一起开发的。这三个产品被设计成一个集成解决方案,称为“Elastic Stack”(以前称为“ELK stack”)。
    Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。再平衡和路由是自动完成的。相关数据通常存储在同一个索引中,该索引由一个或多个主分片和零个或多个复制分片组成。一旦创建了索引,就不能更改主分片的数量。
    Elasticsearch使用Lucene,并试图通过JSON和Java API提供其所有特性。它支持facetting和percolating,如果新文档与注册查询匹配,这对于通知非常有用。另一个特性称为“网关”,处理索引的长期持久性;例如,在服务器崩溃的情况下,可以从网关恢复索引。Elasticsearch支持实时GET请求,适合作为NoSQL数据存储,但缺少分布式事务。

    2.es一些应用

    Elasticsearch虽然是基于Lucene构建,但应用领域确实非常宽泛。

    1)全文检索

    Elasticsearch靠全文检索起步,将Lucene开发包做成一个数据产品,屏蔽了Lucene各种复杂的设置,为开发人员提供了很友好的便利。很多传统的关系型数据库也提供全文检索,有的是基于Lucene内嵌,有的是基于自研,与Elasticsearch比较起来,功能单一,性能也表现不是很好,扩展性几乎没有。

    2)应用查询

    Elasticsearch最擅长的就是查询,基于倒排索引核心算法,查询性能强于B-Tree类型所有数据产品,尤其是关系型数据库方面。当数据量超过千万或者上亿时,数据检索的效率非常明显。

    个人更看中的是Elasticsearch在通用查询应用场景,关系型数据库由于索引的左侧原则限制,索引执行必须有严格的顺序,如果查询字段很少,可以通过创建少量索引提高查询性能,如果查询字段很多且字段无序,那索引就失去了意义;相反Elasticsearch是默认全部字段都会创建索引,且全部字段查询无需保证顺序,所以我们在业务应用系统中,大量用Elasticsearch替代关系型数据库做通用查询,自此之后对于关系型数据库的查询就很排斥,除了最简单的查询,其余的复杂条件查询全部走Elasticsearch。

    3)大数据领域

    Elasticserach已经成为大数据平台对外提供查询的重要组成部分之一。大数据平台将原始数据经过迭代计算,之后结果输出到一个数据库提供查询,特别是大批量的明细数据。

    这里会面临几个问题,一个问题是大批量明细数据的输出,如何能在极短的时间内写到数据库,传统上很多数据平台选择关系型数据库提供查询,比如MySQL,之前在这方面吃过不少亏,瞬间写入性能极差,根本无法满足要求。另一个问题是对外查询,如何能像应用系统一样提供性能极好的查询,不限制查询条件,不限制字段顺序,支持较高的并发,支持海量数据快速检索,也只有Elasticsearch能够做到比较均衡的检索。

    从官方的发布版本新特性来看,Elasticseacrch志在大数据分析领域,提供了基于列示存储的数据聚合,支持的聚合功能非常多,性能表现也不错。
    4)日志检索

    日志自身特点没有什么通用的规范性,人为的随意性很大,日志内容也是任意的,更加需求全文检索能力,传统技术手段本身做全文检索很是吃力。而Elasticsearch本身起步就是靠全文检索,再加上其分布式架构的特性,非常符合海量日志快速检索的场景。

    如今已经从ELK三件套发展到Elastic Stack了,新增加了很多非常有用的产品,大大增强了日志检索领域。

    5)监控领域

    指标监控,Elasticsearch进入此领域比较晚,却赶上了好时代,Elasticsearch由于其倒排索引核心算法,也是支持时序数据场景的,性能也是相当不错的,在功能性上完全压住时序数据库。

    3.基本概念

    1.近实时
    Elasticsearch是一个近实时(Near Real Time,NRT)的数据搜索和分析平台。这意味着从索引文档到可搜索文档都会有一段微小的延迟(通常是1s以内)。
    2.集群
    集群(cluster)是一个或多个节点(node)的集合,这些节点将共同拥有完整的数据,并跨节点提供联合索引、搜索和分析功能。集群由唯一的名称标识(elasticsearch.yml配置文件中对应参数cluster.name),集群的名称是elasticsearch.yml配置文件中最重要的一个配置参数,默认名称为Elasticsearch,节点只能通过集群名称加入集群。 请确保不要在不同的环境中使用相同的集群名称,否则可能会导致节点加入错误的集群。例如,可以使用loggingdev、loggingstage和loggingprod来区分开发、预发布和生产环境的集群。 注意:只有一个节点的集群是有效的,而且有特殊的用处,尤其是可以在单节点集群进行快速的开发、测试。此外,可以存在多个独立的集群,每个集群都有自己唯一的集群名称。
    3.节点
    节点(node)是一个Elasticsearch的运行实例,也就是一个进程(process),多个节点组成集群,节点存储数据,并参与集群的索引、搜索和分析功能。与集群一样,节点由一个名称标识,默认情况下,该名称是在启动时分配给节点的随机通用唯一标识符(UUID)。如果不希望使用默认值,可以定义所需的任何节点名称。此名称对于集群管理很重要,因为在实际应用中需要确定网络中的哪些服务器对应于Elasticsearch集群中的哪些节点。 可以通过集群名称将节点配置为加入特定集群。默认情况下,每个节点都被设置为加入一个名为Elasticsearch的集群,这意味着,如果在网络上启动了多个节点,并且假设它们可以彼此发现,那么它们都将自动形成并加入一个名为Elasticsearch的集群。 在单个集群中,可以有任意多个节点。此外,如果当前网络上没有其他Elasticsearch节点在运行,则默认情况下,启动单个节点将形成一个名为Elasticsearch的新单节点集群。 注意:上面提到了节点实质是一个进程,因此服务器和节点可以是一对多的关系。还有一点需谨记,无论是开发环境、测试环境还是生产环境请配置有意义的节点名称。
    4.索引
    索引(index)是具有某种相似特性的文档集合。例如,可以有存储客户数据的索引,存储产品目录的索引,以及存储订单数据的索引。索引由一个名称(必须全部是小写)标识,当对其中的文档执行索引、搜索、更新和删除操作时,该名称指向这个特定的索引。 在单个集群中,可以定义任意多个索引。
    5.类型
    类型(type)这个概念在7.0版本以后已被彻底移除,因此不再赘述。
    6.文档
    文档(document)是可以被索引的基本信息单元。例如,可以为单个客户创建一个文档,为单个产品创建另一个文档,以及为单个订单创建另一个文档。文档以JSON表示,JSON是一种普遍存在的Internet数据交换格式。在单个索引中,理论上可以存储任意多的文档。

    7.分片和副本
    索引可能会存储大量数据,这些数据可能会超出单个节点的硬件限制。例如,占用1TB磁盘空间的10亿个文档的单个索引可能超出单个节点的磁盘容量,或者速度太慢,无法满足搜索请求的性能要求。 为了解决这个问题,Elasticsearch提供了将索引水平切分为多段(称为分片,shard)的能力。创建索引时,只需定义所需的分片数量。每个分片本身就是一个具有完全功能的独立“索引”,可以分布在集群中的任何节点上。 分片很重要,主要有两个原因:
    · 分片可以水平拆分数据,实现大数据存储和分析。
    · 可以跨分片(可能在多个节点上)进行分发和并行操作,从而提高性能和吞吐量。 如何分配分片以及如何将其文档聚合回搜索请求的机制完全由Elasticsearch管理,并且对用户是透明的。 在随时可能发生故障的网络或云环境中,如果某个分片或节点以某种方式脱机或因何种原因丢失,则强烈建议用户使用故障转移机制。为此,Elasticsearch提出了将索引分片复制一个或多个拷贝,称为副本(replica)。
    副本很重要,主要有两个原因:
    · 副本在分片或节点发生故障时提供高可用性。因此,需要注意的是,副本永远不会分配到复制它的原始主分片所在的节点上。也就是分片和对应的副本不可在同一节点上。这很容易理解,如果副本和分片在同一节点上,当机器发生故障时会同时丢失,起不到容错的作用。
    · 通过副本机制,可以提高搜索性能和水平扩展吞吐量,因为可以在所有副本上并行执行搜索。 总之,每个索引可以分割成多个分片。每个分片可以有零个或多个副本。 可以在创建索引时为每个索引定义分片和副本的数量。创建索引后,还可以随时动态更改副本的数量。分片的数量理论上不可变更,唯一的办法重建索引,重新定义分片数量。但还是可以使用_shrink和_split API更改索引的分片数量,但这不是通常的做法,预先评估准确的分片数量才是最佳方法。 默认情况下,Elasticsearch中的每个索引都分配一个主分片和一个副本,这意味着如果集群中至少有两个节点,则索引将有一个主分片和另一个副本分片(一个完整副本),每个索引总共有两个分片。
    8.分词
    elasticsearch中专门处理分词的组件称之为分词器,英文为analyzer,它由以下几个部分组成。

    character filters:针对原始文本进行处理,比如去除html标签
    tokenizer:将原始文本按照一定规则进行切分
    token filters:针对tokenizer处理过的单词进行再加工,比如大小写转换、助词(的、之、等等)的删除等
    elasticsearch自带的分词器有standard、simple、whitespace、stop、keyword、pattern和language。下面以“The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.”文本为例,演示elasticsearch自带的分词器的分词效果。
    (1).standard
    特性为按词切分、小写处理,其分词结果为[the,2,quick,brown,foxes ,jumped,over,the,lazy,dog’s,bone]。

    (2).simple
    特性为按非字母切分、小写处理,其分词结果为[the,quick,brown,foxes ,jumped,over,the,lazy,dog,s,bone]。

    (3).whitespace
    特性为按空格切分,其分词结果为[the,2,QUICK ,Brown-Foxes ,jumped,over,the,lazy,dog’s,bone.]。

    (4).stop
    特性为按助词(the、an、的、这等)切分、小写处理,其分词结果为[quick,brown,foxes ,jumped,over,lazy,dog,s,bone]。

    (5).keyword
    特性为不分词,直接将输入作为一个单词输出,其分词结果为[The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.]。

    (6).pattern
    特性为通过正则表达式自定义分隔符(默认是\W+,即非字词的符号作为分隔符)、小写处理,其分词结果为[the,2,quick,brown,foxes, jumped,over, the,lazy,dog,s,bone]。

    (7).language
    特性为按语言(阿拉伯、英语等)切分。

    一些基本操作

    1、索引操作
    1)查看es实例中所有索引
    GET http://127.0.0.1:9200/_cat/indices?v

    2)创建一个索引
    PUT http://127.0.0.1:9200/shopping
    3)查看单个索引
    GET http://127.0.0.1:9200/shopping
    4)删除索引
    DELETE http://121.40.182.123:9200/shopping

    2、文档操作
    1)创建文档
    POST请求和PUT请求都可以创建文档

    创建文档时,POST可以携带ID也可以不携带ID,但是PUT请求必须要携带ID

    创建文档时,POST请求携带ID,如果ES中有相同的文档,则为修改,但是version一直增加

    创建文档时,PUT请求携带ID,如果ES中有相同的文档,则为修改,但是version不会增加

    POST http://121.40.182.123:9200/shopping/_doc
    { 
    	"title":"小米手机", 
    	"category":"小米", 
    	"images":"http://www.gulixueyuan.com/xm.jpg", 
    	"price":3999.00
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2)查询单个文档
    GET http://121.40.182.123:9200/shopping/_doc/1

    3)修改文档 (全量覆盖)
    和新增文档一样,输入相同的URL地址请求,如果请求体变化,会将原有的数据内容覆盖 在 Postman 中,向 ES 服务器发 POST请求 :http://127.0.0.1:9200/shopping/_doc/1

    POST http://121.40.182.123:9200/shopping/_doc/1
    { 
    	"title":"华为手机手机", 
    	"category":"小米", 
    	"images":"http://www.gulixueyuan.com/xm.jpg", 
    	"price":3999.00
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4)修改字段
    修改数据时,也可以只修改某一给条数据的局部信息

    POST http://121.40.182.123:9200/shopping/_update/1
    { 
    	"doc": {
    		"title":"apple pro18"
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5)删除文档
    删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)

    DELETE http://121.40.182.123:9200/shopping/_doc/1
    6)根据条件删除文档
    POST http://121.40.182.123:9200/shopping/_delete_by_query
    {
    “query”: {
    “match”: {
    “title”: “小米手机”
    }
    }
    }
    3、映射操作
    1)创建映射
    PUT http://127.0.0.1:9200/student/_mapping

    {
        "properties": {
            "name": {
                "type": "text",
                "index": true
            },
            "sex": {
                "type": "text",
                "index": false
            },
            "age": {
                "type": "long",
                "index": false
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    映射字段说明:

    type:类型,Elasticsearch 中支持的数据类型非常丰富,说几个关键的:

    ​ String 类型,又分两种:

    ​ text:可分词

    ​ keyword:不可分词,数据会作为完整字段进行匹配

    ​ Numerical:数值类型,分两类

    ​ 基本数据类型:long、integer、short、byte、double、float、half_float

    ​ 浮点数的高精度类型:scaled_float

    ​ Date:日期类型

    ​ Array:数组类型

    ​ Object:对象

    index:是否索引,默认为 true,也就是说你不进行任何配置,所有字段都会被索引。

    ​ true:字段会被索引,则可以用来进行搜索

    ​ false:字段不会被索引,不能用来搜索

    store:是否将数据进行独立存储,
    4、高级查询
    1)查询所有文档
    POST http://121.40.182.123:9200/student/_search

    {
        "query":{
            "match_all":{}    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2)匹配查询
    POST http://121.40.182.123:9200/student/_search

    {
        "query":{
            "match":{
            	"name": "zhangsan"
            }    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3)多字段匹配查询
    POST http://121.40.182.123:9200/student/_search

    {
    	 "query": {
    		 "multi_match": {
    			 "query": "zhangsan",
    			 "fields": ["name","nickName"]
    		  }
    	 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4)关键字精确查询
    http://121.40.182.123:9200/student/_search

    {
    	 "query": {
    		 "term": {
    			 "name":{
    			 	"value":"zhangsan"
    			 }
    		  }
    	 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5)多关键字精确查询 term
    terms 查询和 term 查询一样,但它允许你指定多值进行匹配。 如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件

    http://121.40.182.123:9200/student/_search

    {
    	 "query": {
    		 "term": {
    			 "name":["zhangsan","lisi"]
    		  }
    	 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    spring整合elastic

    Spring boot 2.5.x整合ElasticSearch 7.1x
    es模糊查询、分词查询、精确查询
    ElasticsearchTemplate的详细使用,完成多条件查询、匹配度查询等

    项目保存数据思路

    可以从excel表中读,也可以从mysql中读取数据然后保存到Es中,由于只存公司名,因此公司名作为id:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @Builder
    @Document(indexName = "company")
    public class Company {
        @Id
        @Field(type = FieldType.Text)
    //    @JsonIgnore
        private String id;
        @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
        private String name;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
      @ApiOperation("保存")
        @GetMapping("/save")
        public Result<List<Company>> save() {
            Company company = new Company();
            company.setId("安徽省xx有限公司");
            company.setName("安徽省xx有限公司");
       
            esService.save(company);
            return Result.success(esService.findAll());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    Mysql索引分类及其使用实例
    【Graph Net学习】DeepWalk/Node2Vec实现Graph Embedding
    MySQL数据库安装配置保姆级教程(以8.0.29为例)有手就行
    什么是React的虚拟DOM(Virtual DOM)?它的作用是什么?
    搭建免费的ftp服务器
    docker0: iptables: No chain/target/match by that name
    ARM32开发——GPIO输入
    Jmeter(九):jmeter_逻辑控制器与HTTP Cookie管理器详解
    【从安装JDK开始】Spring Cloud + Apache Ignite简单实例
    DayZ服务器一机多服的设置方法教程
  • 原文地址:https://blog.csdn.net/qq_41358574/article/details/128093213