Elasticsearch入门,看完又要会!慎点

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
日志服务 SLS,月写入数据量 50GB 1个月
简介: 本文主要介绍 ElasticSearch的使用

ELK是一个免费开源的日志分析架构技术栈总称,其中包含三大基础组件,分别是 ElasticSearchLogstashKibanaELK在实际开发中不仅仅使用于日志分析,它还可以支持其他任何数据搜索、分析和收集的场景,其中日志分析和收集更具有代表性。


既然 ELK 这么有用,那这篇我们就先来认识一下什么是 ElasticSearch吧!


简介


简单来说 ElasticSearch 就是一个搜索框架。对于搜索这个词我们并不陌生,当我们输入关键词后,返回含有该关键词的所有信息结果。


在我们平时用到最多的便是数据库搜索:


SELECT * FROM USE WHERE NAME LIKE %小菜%


但是用数据库做搜索存在着许多弊端,例如:


  • 存储问题:当数据量大的时候就必须进行分库分表。


  • 性能问题:当数据量过大时,使用LIKE会对上亿条数据进行逐行扫描,性能受到严重影响。


  • 不能分词:当我们搜索 游戏本电脑 的时候,只会返回完全和关键词一样的数据,如果搜索 游戏电脑,那么是不是就会没有数据返回。


因此基于以上问题,ElasticSearch出现了。它是使用 Java 开发的,基于 Lucene、分布式、通过 Restful 方式进行交互的近实时搜索平台框架。它的优点如下:


  • 分布式的搜索引擎和数据分析引擎


  • 全文检索,结构化检索和数据分析


  • 对海量数据进行近实时的处理


Lucene 介绍


Lucene 是一个功能强大的搜索库,如果我们直接基于 Lucene 开发,那么会非常复杂。而 ElasticSearch 是基于 Lucene 开发的,封装了许多 Lucene 底层功能,提供了简单易用的 RestFul api接口和许多语言的客户端。


ElasticSearch核心概念


  • NRT(Near Realtime) 近实时


  1. 写入数据时,过 1 秒才会被搜索到,因为内部需要分词,引入索引
  2. es 搜索和分析数据都是秒级内出结果


  • Cluster 集群


包含一个或多个启动着es实例的机器群。通常一台机器起一个es实例。同一网络下,集名一样的多个es实例自动组成集群,自动均衡分片等行为。默认集群名为“elasticsearch”。


  • Node 节点


每个es实例称为一个节点。节点名自动分配,也可以手动配置。


  • Index 索引


包含一堆有相似结构的文档数据。索引创建规则:


  1. 仅限小写字母
  2. 不能包含 \、/、 *、?、"、<、>、|、# 以及空格符等特殊符号
  3. 7.0版本开始不再包含冒号
  4. 不能以**-、_+**开头
  5. 不能超过255个字节(注意它是字节,因此多字节字符将计入255个限制)


  • Document 文档


es中的最小数据单元。一个document就像数据库中的一条记录。通常以json格式显示。多个document存储于一个索引(Index)中。


  • Field 字段


就像数据库中的列(Columns),定义每个document应该有的字段。


  • Type 类型


每个索引里都可以有一个或多个typetypeindex中的一个逻辑数据分类,一个type下的document,都有相同的field


:6.0之前的版本有type(类型)概念,type相当于关系数据库的表,ES官方将在ES9.0版本中彻底删除type。本教程typy都为_doc。


  • Shard 分片


index数据过大时,将index里面的数据,分为多个shard,分布式的存储在各个服务器上面。可以支持海量数据和高并发,提升性能和吞吐量,充分利用多台机器的cpu


  • replica 副本


在分布式环境下,任何一台机器都会随时宕机,如果宕机,index一个分片都没有,那么导致此index不能搜索。所以,为了保证数据的安全,我们会将每个index的分片进行备份,存储在另外的机器上。保证少数机器宕机es集群仍可以搜索。


能正常提供查询和插入的分片我们叫做主分片(primary shard),其余的叫做备份的分片(replica shard)。


与数据库同比


关系型数据库 非关系型数据库(Elasticsearch)
数据库 Database 索引 Index
Table 索引 Index(原为 Type
数据行 Row 文档 Document
数据列 Column 字段 Field
约束 Schema 映射 Mapping


前期准备


演示环境: Windows


ElasticSearch 安装


我们进入 ElasticSearch下载地址  下载和解压 ElasticSearch ,目录结构如下:


  • bin:脚本目录,包括:启动、停止等可执行的脚本


  • config:配置文件目录


  • data:索引目录


  • logs:日志目录


  • modules:模块目录,包括了 es 的功能模块


  • plugins:插件目录,es 支持插件机制


准备好配置文件后,双击elasticsearch.bat启动,接着访问http://localhost:9200,出现以下界面即为成功:


网络异常,图片无法展示
|


Kibana 安装


进入下载地址 下载和解压 Kibana,修改配置文件后,双击kibana.bat启动,接着访问http://localhost:5601/,出现以下界面即为成功:


网络异常,图片无法展示
|


进入 Kibana 控制台,输入 GET /查看ElasticSearch信息,出现以下界面即为成功:


网络异常,图片无法展示
|


前期准备工作做好了,咱们现在开始进入ElasticSearch的正式环节!


ES开讲


什么是 Index


Index就相当于数据库中的数据表,ElasticSearch会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。所以,ElasticSearch数据管理的顶层单位就叫做 Index(索引)注: 每个 Index 的名字必须是小写。


  • 创建一个 test 索引:


语法:PUT /${index}


网络异常,图片无法展示
|


  • 删除 test 索引:


语法:DELETE /${index}


网络异常,图片无法展示
|


其中删除支持其他语法:


1. DELETE /test
2. DELETE /test1,test2
3. DELETE /test_*
4. DELETE /_all


什么是 Document


首先员工和部门对象如下:


public class Employee{
    private String id;
    private String name;
    private String deptId;
}
public class Department{
    private String id;
    private String deptName;
    private String describe;
}


我们如果用关系型数据存数据的话,应该是一个员工表和一个部门表,查询员工的时候想要带上部门的信息就得使用关联查询。


但是在 ES 中,它是面向文档的,文档中存储的数据结构与对象一致。一个对象可以直接保存成一个文档,这就是ES中的 Documentdocument 是采用 json 数据格式表示,示例如下:


{
    "id":"1",
    "name":"小菜",
    "department":{
        "id":"1",
        "deptName":"搬砖部",
        "describe":"努力搬好每一块砖"
    }
}


接下来我们在 employee索引中演示基本的增删改查操作:


创建员工信息


网络异常,图片无法展示
|


获取员工信息


网络异常,图片无法展示
|


修改员工信息


以下是替换操作,要带上所有信息


网络异常,图片无法展示
|


局部更新操作


网络异常,图片无法展示
|


局部更新操作的语法为:POST /{index}/_update/{id},其中要更新的信息需要放在doc里面


删除员工信息


网络异常,图片无法展示
|


字段信息


{
  "_index" : "employee",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "_seq_no" : 7,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "id" : "1",
    "name" : "小菜",
    "department" : {
      "id" : "1",
      "deptName" : "搬砖部",
      "describe" : "努力搬好每一块砖"
    }
  }
}


当我们通过GET /employee/_doc/1 可以获取到一条文档信息如上,其中出现 8 个字段,接下来为你们解析一番重要字段:


  • _index:文档所属的索引名称


  • _type:类别。在 es9 只有会删除此字段,因此不用关注,默认都为 _doc


  • _id:文档的唯一标志,类似于表中的主键ID,可以用来标识和定义一个文档。可以手动生成,也可以自动生成


  1. 手动生成
PUT /employee/_doc/1
{
    "id":"1",
    "name":"小菜",
    "department":{
        "id":"1",
        "deptName":"搬砖部",
        "describe":"努力搬好每一块砖"
    }
}


  1. 自动生成:
  • 注: 这里用到是 POST请求,将会为我们自动生成 20 个字符的 ID


POST /employee/_doc
{
    "id":"3",
    "name":"小王",
    "department":{
        "id":"1",
        "deptName":"搬砖部",
        "describe":"努力搬好每一块砖"
    }
}


  • 网络异常,图片无法展示
    |


  • _version:版本号


这里的版本号是在 全量替换局部更新删除 操作时,版本号都会加 1,上面 ID 为 1 的员工信息版本包为4,说明这条记录已经更新了 4 次。


  • _seq_no:序列号


作用于 version 类似,当数据发生变更时,值就会加 1


  • _source:插入数据时的所有字段和值


我们也可以不需要返回所有字段,需要用以下语句:


GET /employee/_doc/1?_source_includes=id,name


网络异常,图片无法展示
|


当然不仅可以使用_source_includes  ,还可以使用_source_excludes,两个意思分别是包括排除


乐观锁机制


在我们学习 Java 并发的时候,我们认识了 CAS 乐观锁机制,在 ES 中我们同样也可以使用乐观锁来控制。


CAS是基于版本号的,而在上述 Document 字段解析中,我们也看到了 _seq_no 这个字段,不由想象,我们是否也能根据 _seq_no 来做乐观锁控制解决并发问题呢,答案是可以的。


我们首先创建一条员工记录:


网络异常,图片无法展示
|


此时,版本号毋庸置疑是 1_seq_no10


然后我们将这条员工信息删除:


网络异常,图片无法展示
|


接着我们重新创建一条相同的员工信息:


网络异常,图片无法展示
|


可以看到这个时候的版本号变成了 3_seq_no 变成了 14


这是因为 ES 内部采用了 延迟删除策略,这是因为如果删除一条数据里吗删除的话,所有分片和副本都要立马删除,这会对 ES 集群压力太大。


进行并发控制:


  • 步骤1:我们先查出当前的 _seq_no17


语句:PUT /employee/_doc/5?if_seq_no=17&if_primary_term=1


网络异常,图片无法展示
|


可以看到更新后,_version_seq_no 都加上了 1


如果 _seq_no 版本不匹配的情况下:


网络异常,图片无法展示
|


将会报出错误!


批量操作


批量查询 (_mget)


上面我们用到的语句都是指定ID单个查询,如果我们想要查询当前索引下的所有数据,那么应当使用以下语句:


GET /employee/_mget
{
  "docs" : [
      {
         "_id" : 1
      },
      {
         "_id" : 5
      }
   ]
}


网络异常,图片无法展示
|


如果我们要同时查询不同索引下的 ID 时,应当使用以下语句:


GET /_mget
{
   "docs" : [
      {
         "_index" : "employee",
         "_id" : 1
      },
      {
         "_index" : "employee",
         "_id" : 5
      }
   ]
}


网络异常,图片无法展示
|


批量增删改 (bulk)


语法:


POST /_bulk
{"action": {"metadata"}}
{"data"}


示例:


网络异常,图片无法展示
|


注:


  • delete: 删除一个文档,只需 1 个 json


  • create: 创建一个文档,相当于  PUT /index/type/id/_create


  • index: 普通的 put 操作,可以创建文档,也可以全量替换文档


  • update: 更新一个文档,执行的是局部更新


每个操作之间互不影响,操作失败的行会返回对应的失败信息


buld 操作请求一次不易过大, 否则一下子容易挤压到内存中,性能会下降


与开发融合


ElasticSearch 是基于 Java 开发的,当然我们开发中要使用 ElasticSearch 也是非常方便的。


首先便是引入依赖


<dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.9.0</version>
        <exclusions>
            <exclusion>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.9.0</version>
    </dependency>


获取员工信息示例


网络异常,图片无法展示
|


/** OUTPUT:
{"id":"1","name":"小菜啊","department":{"id":"1","deptName":"搬砖部","describe":"努力搬好每一块砖"}}
 */


如果你觉得只从 getResponse 中获取一个 source 不满足,没有关系!我们还可以从getResponse 获取以下信息:


网络异常,图片无法展示
|


我们在上面的查询文档中发现,如果需要从 ES 中获取信息,我们先要 获取客户端连接,然后再 构建请求,最后 执行得到结果。这一系列操作不知道你是否有点熟悉,我们以前用的 JDBC,也是需要这一系列的操作,后来出现了 HibernateMybatis,大大简化了我们的代码量。无独有偶,ES 也可以完美结合 Spring 框架开发。


首先我们需要需要在 application.yaml 文件中定义好elasticsearchhost


server:
  port: 8081
spring:
  application:
    name: search-service
  elasticsearch:
    address: 127.0.0.1:9200 #多个节点用逗号分隔


然后我们需要在 Spring 中注册 RestHighLevelClient


网络异常,图片无法展示
|


执行查询


网络异常,图片无法展示
|


我们在上述例子中认识到了_source_includes  和_source_excludes的用法,当然在 Java 中也是支持的:


网络异常,图片无法展示
|


而且ESJava 中还支持异步查询:


网络异常,图片无法展示
|


执行新增


网络异常,图片无法展示
|


在上面我们是用 json 传递我们需要新增的参数,当然也支持另外方式:


//方式1: json
Map<String, String> insertInfo = new HashMap<>();
insertInfo.put("id", "8");
insertInfo.put("name", "老王");
request.source(JSON.toJSONString(insertInfo), XContentType.JSON);
//方式2: map
Map<String, String> insertInfo = new HashMap<>();
insertInfo.put("id", "8");
insertInfo.put("name", "老王");
request.source(insertInfo);
//方式3: XContentBuilder
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
    builder.field("id", "8");
    builder.field("name", "老王");
}
builder.endObject();
request.source(builder);
//方式4: 直接构建
request.source("id", "8", "name", "老王");


当然不止新增支持异步操作,更新同样也支持异步操作:


网络异常,图片无法展示
|


执行修改


网络异常,图片无法展示
|


异步支持:


网络异常,图片无法展示
|


执行删除


网络异常,图片无法展示
|


异步支持:


网络异常,图片无法展示
|


执行批量


网络异常,图片无法展示
|


Mapping 介绍


什么是Mapping: 自动或手动为 index 中的 _doc 建立的一种数据结构和相关配置

我们如果使用关系型数据库插入一条员工信息,首先需要建立一个员工表 employee,然后表里面有两个字段:idname


create table website(
    id varchar(8),
    name varchar(8)
);


我们往 员工索引 中插入数据:


PUT /employee/_doc/1
{
    "id":"1",
    "name":"小菜"
}


感觉少了点什么,那就是我们不需要建立字段了,甚至不需要手动建立 employee 索引,只需要一句语句就可以解决!


这是因为ES 里面存在动态映射(Dynamic Mapping),会自动为我们建立 index,以及对应的 mappingmapping 中包含了每个 field 对应的数据类型,以及如何分词等设置。


我们可以通过 GET /{index}/_mapping 查看自己索引的字段映射:


网络异常,图片无法展示
|


核心数据类型


网络异常,图片无法展示
|


动态推测类型


网络异常,图片无法展示
|


JSON datatype ElasticSearch datatype
true or false boolean
123 long
123.45 double
2019-01-01 date
"test" text/keyword


自定义


我们在创建完索引后,可以手动创建映射:


语法:PUT ${index}/_mapping


PUT department/_mapping
{
    "properties": {
        "id": {
            "type": "text"
        },
        "description": {
            "type": "text",
            "analyzer":"english",
            "search_analyzer":"english"
        }
    }
} 


其中可以通过analyzer属性指定分词器。上边指定了analyzer是指在索引和搜索都使用english,如果单独想定义搜索时使用的分词器则可以通过search_analyzer属性。

注: 日期类型不支持分词器


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
6月前
|
安全 Linux 开发工具
Elasticsearch 搜索入门技术之一
Elasticsearch 搜索入门技术之一
257 1
|
6月前
|
JSON 自然语言处理 数据库
数据库-ElasticSearch入门(索引、文档、查询)
数据库-ElasticSearch入门(索引、文档、查询)
386 0
|
存储 关系型数据库 数据库
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
|
1月前
|
存储 Java API
Elasticsearch 7.8.0从入门到精通
这篇文章详细介绍了Elasticsearch 7.8.0的安装、核心概念(如正排索引和倒排索引)、RESTful风格、各种索引和文档操作、条件查询、聚合查询以及在Spring Boot中整合Elasticsearch的步骤和示例。
135 1
Elasticsearch 7.8.0从入门到精通
|
2月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
|
2月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
|
8天前
|
存储 JSON Java
ELK 圣经:Elasticsearch、Logstash、Kibana 从入门到精通
ELK是一套强大的日志管理和分析工具,广泛应用于日志监控、故障排查、业务分析等场景。本文档将详细介绍ELK的各个组件及其配置方法,帮助读者从零开始掌握ELK的使用。
|
3月前
|
JSON 搜索推荐 数据挖掘
ElasticSearch的简单介绍与使用【入门篇】
这篇文章是Elasticsearch的入门介绍,涵盖了Elasticsearch的基本概念、特点、安装方法以及如何进行基本的数据操作,包括索引文档、查询、更新、删除和使用bulk API进行批量操作。
ElasticSearch的简单介绍与使用【入门篇】
|
2月前
|
JSON 监控 Java
Elasticsearch 入门:搭建高性能搜索集群
【9月更文第2天】Elasticsearch 是一个分布式的、RESTful 风格的搜索和分析引擎,基于 Apache Lucene 构建。它能够处理大量的数据,提供快速的搜索响应。本教程将指导你如何从零开始搭建一个基本的 Elasticsearch 集群,并演示如何进行简单的索引和查询操作。
227 3
|
3月前
|
JSON 测试技术 API
黑马商城 Elasticsearch从入门到部署 RestClient操作文档
这篇文章详细介绍了如何使用Java的RestHighLevelClient客户端与Elasticsearch进行文档操作,包括新增、查询、删除、修改文档以及批量导入文档的方法,并提供了相应的代码示例和操作步骤。
下一篇
无影云桌面