快速入门Elasticsearch:安装、基本概念、分词器和文档基本操作详解

本文主要介绍快速入门 Elasticsearch,从 安装基本概念分词器 、*** 文档基本操作 *** 这 4 个方面快速入门。

Elasticsearch 是一款近实时的搜索引擎,底层是基于 Lucene 做搜索,再此基础上加入了分布式的特性,以便支持海量数据的存储和搜索。

1、安装

1.1、安装 ES

安装 ES,就 3 步: 下载解压修改配置文件启动 ,本文选择的 ES 版本是7.10.2

1.1.1、在 Linux 机器下载对应版本,然后解压

复制代码
# 下载
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.2-linux-x86_64.tar.gz
# 解压
tar -zxvf elasticsearch-7.10.2-linux-x86_64.tar.gz
mv elasticsearch-7.10.2 elasticsearch

1.1.2、修改配置文件

进入elasticsearch目录下的 elasticsearch.yml修改如下属性:

cluster.name:集群名称,根据自己业务启个合适的名字

node.name:给节点起个名字,一般使用node-1node-2 、...

path.data:数据存放的位置,比如:/data/elasticsearch/data

path.logs:日志存放的位置,比如:/data/elasticsearch/logs

network.host:配置成本机 IP 地址,用于集群机器之间相互通信。

http.port:ES 服务访问的端口号,比如:9200

discovery.seed_hosts:配置为 master 候选者节点。如果要与其他节点组成集群,这里必须配置。比如:["10.20.1.29", "10.20.0.91", "10.20.0.93"]

cluster.initial_master_nodes:首次启动集群时,配置主节点的候选节点,该配置里的节点都是候选节点。比如:["node-1", "node-2", "node-3"]

1.1.3、启动

进入到elasticsearch目录下执行如下命令启动 ES。

复制代码
./bin/elasticsearch -d

不过一般会出现如下 3 个错误,一个个搜索解决就行:

  • 不能以 root 用户启动 ES,所以在启动之前要先创建一个系统用户,然后su xxxxxx切换到该用户去启动。

  • 虚拟内存不够,报错如下:max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]。此时需要修改sysctl.conf文件,vim /etc/sysctl.conf进入文件,调大vm.max_map_count=262144

  • 可操作性的文件句柄数不够,报错如下:max file descriptors [65535] for elasticsearch process is too low。进入文件vim /etc/security/limits.conf,调大句柄数。

    *** hard nofile 65536
    *** soft nofile 65536

1.1.4、访问 ES

访问 ES 地址http://10.20.1.29:9200/,出现如下界面说明成功。

1.2、安装 ES 集群

比如安装一个 3 台节点的集群,每台节点安装步骤与单机类似,都是 下载解压修改配置文件启动 。配置需要注意的地方是discovery.seed_hostscluster.initial_master_nodes,集群场景下要配置多台。如果安装分词器,每台节点都需要安装,下面会介绍到。

1.3、安装集群可视化工具

一般会使用 Chrome 插件Multi Elasticsearch Head或者Cerebro这两款工具观察 ES 集群的整体情况。

1.3.1、安装 Chrome 插件 - Multi Elasticsearch Head

直接在 Chrome 浏览器应用市场搜索安装Multi Elasticsearch Head。安装完之后输入 ES 集群地址,就可以看到集群概况了。这个工具里也有其他功能,很少会使用到,一般只用来观察集群和查看索引数据。

1.3.2、安装 Cerebro

Cerebro 这款工具与Multi Elasticsearch Head类似,也是用来管理 ES 集群。Cerebro 项目地址:https://github.com/lmenezes/cerebro,这个项目也是好久没更新了。

安装过程 ,如下:

复制代码
wget https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4.tgz
tar -zxvf cerebro-0.9.4.tgz
cd cerebro-0.9.4
./bin/cerebro >> cerebro.log 2>&1 &

安装之后,界面如下:

1.4、安装 Kibana

Kibana 是数据分析和数据可视化平台,一般配合 ELK 作为日志整理解决方案,用它来查看日志。虽然有许多应用场景,不过笔者一般用它来查询 ES 数据,或者调试 ES 的接口。

其实Multi Elasticsearch HeadCerebro也有查询数据的功能,但是整体使用起来没有 Kibana 方便,也没有智能提示。所以如果想查询 ES 数据,或者调试 ES 接口,还是非常建议使用 Kibana。

安装过程 ,如下:

  1. 下载解压

    wget https://artifacts.elastic.co/downloads/kibana/kibana-7.10.0-linux-x86_64.tar.gz
    tar -zxvf kibana-7.10.0-linux-x86_64.tar.gz
    mv kibana-7.10.0-linux-x86_64 kibana
    cd kibana

  2. 修改配置
    server.host:方便外部访问,此处改成 "0.0.0.0"
    elasticsearch.hosts:把 ES 集群地址全部写上

  3. 启动,注意备注里写的停止的步骤

    启动使用如下命令

    但是停止kibana进程时,需要使用 netstat -tunlp|grep 5601 命令找到进程号,然后kill。

    直接使用ps -ef|grep kibana是找不到进程的,因为kibana运行在nodejs进程里,或者使用 ps -ef|grep node 查找Nodejs进程,然后kill

    ./bin/kibana >> kibana.log 2>&1 &

  4. 访问,http://10.20.1.29:5601/app/dev_tools#/console,进入到开发工具界面:

1.5、简单运行

一般读写 ES 分为 3 步:创建 Mapping、写入数据、查询数据。

1.5.1、创建 Mapping ,比如创建一个 testusers 数据结构

复制代码
PUT testusers
{
  "mappings": {
    "properties": {
        "id": {
          "type": "keyword"
        },
        "name": {
          "type": "text"
        },
        "age": {
          "type": "integer"
        }
      }
  }
}

结果如下:

1.5.2、写入数据

复制代码
POST /testusers/_doc
{
  "id":"1",
  "name":"不焦躁的程序员",
  "age":10
}

1.5.3、查询数据

复制代码
POST /testusers/_search
{
  "query": {
    "match_phrase": {
      "name": "不焦躁"
    }
  }
}

结果如下:

2、基本概念


基础工作准备好之后,就开始了解 Elasticsearch 里的基本概念了。

ES 的基本概念除了集群、节点之外,还有: 索引Mapping文档字段分词分词器分片副本倒排索引

  • 索引 :索引是某一类文档的集合,类似 Mysql 的数据库。
  • Mapping :Mapping 是定义索引中有哪些字段,以及字段类型,以及字段是否会分词等,类似数据库中定义的表结构。
  • 文档 :文档就是索引里的一条记录,类似数据库表中的一行记录。
  • 字段 :文档有一个或多个字段,每个字段有指定的类型,常用的类型有:keyword、text、数字类型(integer、long、float、double 等)、日期类型、对象类型等。类型是text类型时,创建文档时 ES 会对该字段进行分词操作,其余类型则不会做分词。
  • 分词 :ES 里最核心的概念就是分词了,ES 会对text类型的字段进行分词,分词后就会得到一个个的词项,常用Term表述。
  • 分词器 :ES 里有各种各样的分词器,用于不用场景下对text类型的字段进行分词。
  • 分片 :分片实际上是将某个索引的数据切分成多个块,然后均匀地将各个块分配到集群里的各个 Node 节点上。可以通过 ES 的策略查找数据块所在的 Node。这种方案是面向海量数据而设计的,这样数据可以分布在各个节点上,数据量扩张时通过扩充 Node 数量来快速解决。
  • 副本 :只要涉及到分布式的场景,几乎都有副本的概念。副本主要是为了备份数据,保障数据的安全性。同时也可以将查询请求分摊到各个副本里,缓解系统压力,提高吞吐量。ES 里的数据分为主分片和副本分片,写数据时先写入主分片,然后在异步写入副本分片。
  • 倒排索引 :比如我们常用的数据库索引,是把索引字段建立目录,保存目录和数据的关系,然后根据目录去查找文档,使用 B+ 树来实现。但是倒排索引(又称反向索引),是根据分词后的 Term 与文档建立关系,每个 Term 都对应着一堆文档,然后搜索文本时先将文本分词,然后去匹配 Term,然后再去根据匹配的得分找出相关文档。

3、分词器


分词说白了通过分词器将文本转换为各种 Term 的过程。ES 内置了多种分词器,Standard Analyzer 是默认的分词器,它将文本按单词切分并且转为小写,一般用于英文分词,另外还有多种中文分词器,本文以 IK 分词器为例。

3.1安装 IK 分词器

在中文场景下,一般会选择IK 分词器IK分词器需要单独安装,如果是集群场景,每台节点都需要安装,安装如下:

复制代码
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.10.2/elasticsearch-analysis-ik-7.10.2.zip

在每个节点安装之后,需要重启 ES 才能使IK分词器 插件生效。

3.2 查看分词效果

重启后,可以在 Kibana 中测试一下IK 分词器的效果。IK 分词器有两种模式: ik_max_word 和 ik_smart

  • ik_max_word: 会做细粒度的拆分,尽量找出各种可能的组合。ik_max_word 适合 Term 词项查询,因为 Term 查询不会对查询文本做分词,所以最好是在创建文档尽量拆分出更多可能性的词,才能尽量的与查询文本匹配上。Term词项查询会在下文介绍。
  • ik_smart: 类似于稍微聪明点的分词,拆分粒度会粗一些。ik_smart 适合 match phrase 短语匹配查询。因为 match phrase 短语匹配查询要求查询文本被分词后要被连续匹配上,所以最好文档在分词时尽量分的粒度要粗一些。match phrase 短语匹配查询会在下文介绍。

测试 ik_max_word 场景:

复制代码
POST _analyze
{  
    "analyzer": "ik_max_word",
    "text": "中华人民共和国国歌"  
}

ik_max_word 场景的结果:

复制代码
{
  "tokens" : [
    {
      "token" : "中华人民共和国",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "中华人民",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "中华",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "华人",
      "start_offset" : 1,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "人民共和国",
      "start_offset" : 2,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "人民",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 5
    },
    {
      "token" : "共和国",
      "start_offset" : 4,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 6
    },
    {
      "token" : "共和",
      "start_offset" : 4,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 7
    },
    {
      "token" : "国",
      "start_offset" : 6,
      "end_offset" : 7,
      "type" : "CN_CHAR",
      "position" : 8
    },
    {
      "token" : "国歌",
      "start_offset" : 7,
      "end_offset" : 9,
      "type" : "CN_WORD",
      "position" : 9
    }
  ]
}

测试 ik_smart 场景:

复制代码
POST _analyze
{  
    "analyzer": "ik_smart",
    "text": "中华人民共和国国歌"  
}

ik_smart 场景结果:

复制代码
{
  "tokens" : [
    {
      "token" : "中华人民共和国",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "国歌",
      "start_offset" : 7,
      "end_offset" : 9,
      "type" : "CN_WORD",
      "position" : 1
    }
  ]
}

4、文档基本操作


以上将入门内容讲完,下面做一些文档实操。文档基本操作包括:创建索引、新建文档、更新文档、删除文档、查询文档。

4.1、创建 Mapping、创建索引

创建 Mapping,实际上也是创建索引。

复制代码
PUT /goods
{
  "mappings": {
    "properties": {
      "brandName": {
        "type": "keyword"
      },
      "categoryName": {
        "type": "keyword"
      },
      "createTime": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "id": {
        "type": "keyword"
      },
      "price": {
        "type": "double"
      },
      "saleNum": {
        "type": "integer"
      },
      "status": {
        "type": "integer"
      },
      "stock": {
        "type": "integer"
      },
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      }
    }
  }
}

4.2、新建文档

有 2 种方式,Index API方式 和 Create API方式:

  • Index API 方式 ,这种方式创建文档时,碰到相同的文档 id,依旧会创建成功,但会删掉旧的创建新的。

PUT 索引名称/_doc/文档id

复制代码
PUT goods/_doc/1
{
  "id": 1,
  "brandName": "Apple",
  "categoryName": "手机",
  "createTime": "2023-10-22 19:12:56",
  "price": 8799,
  "saleNum": 599,
  "status": 0,
  "stock": 1000,
  "title": "Apple iPhone 13 Pro (A2639) 256GB 远峰蓝色 支持移动联通电信5G 双卡双待手机"
}
  • Create API 方式 ,这种方式创建文档时,碰到相同文档 id,则创建失败。

PUT 索引名称/_create/文档id

复制代码
PUT goods/_create/1
{
  "id": 1,
  "brandName": "Apple",
  "categoryName": "手机",
  "createTime": "2023-10-22 19:12:56",
  "price": 8799,
  "saleNum": 599,
  "status": 0,
  "stock": 1000,
  "title": "Apple iPhone 13 Pro (A2639) 256GB 远峰蓝色 支持移动联通电信5G 双卡双待手机"
}

4.3、更新文档

POST 索引名称/_update/文档id

复制代码
POST goods/_update/1
{
  "doc": {
    "title":"Apple iPhone 13 Pro (A2639) 256GB 远峰蓝色 支持移动联通电信5G 双卡双待手机111"
  }
}

4.4、删除文档

DELETE 索引名称/文档id

复制代码
DELETE goods/_doc/1

4.5、查询文档

查询主要分为: match 匹配查询term 词项查询组合查询聚合统计 。本文主要介绍 match 匹配查询term 词项查询

4.5.1 match 匹配查询

  • match 匹配查询

如果查询字段是文本,则会对文本进行分词,只要分词后的 Term 存在于文档中,就返回对应的文档。

如果查询的字段是日期、keyword、数字等精确类型,则不会进行分词,必须要查询的内容在文档里完全匹配上,才会返回对应的文档。

使用如下:

复制代码
// 这种方式查到数据
POST goods/_search
{
  "query": {
    "match": {
      "categoryName": "手机"
    }
  }
}
// 这种方式查不到数据,categoryName是keyword类型,不做分词,必须完全匹配
POST goods/_search
{
  "query": {
    "match": {
      "categoryName": "手机多余"
    }
  }
}

// 这种方式查到数据
POST goods/_search
{
  "query": {
    "match": {
      "title": "移动"
    }
  }
}
// 这种方式查到数据,title是text类型,会做分词,只要有分词能匹配上就行
POST goods/_search
{
  "query": {
    "match": {
      "title": "移动多余"
    }
  }
}
  • match phrase 短语匹配查询

短语匹配查询要求就比较高了,短语匹配会对查询的内容进行分词,分词后的 Term 必须全部出现在文档中,并且顺序必须一致,才会返回对应的文档,当然这个一致的程度也是可以调整的。

使用如下:

复制代码
// 这样可以查到数据
POST goods/_search
{
  "query": {
    "match_phrase": {
      "title": "移动联通"
    }
  }
}
// 这样查不到数据,短语匹配时,虽然做了分词,但是要分词后的顺序一致,索引匹配补上
POST goods/_search
{
  "query": {
    "match_phrase": {
      "title": "联通移动"
    }
  }
}

4.5.2 Term 词项查询

Term 词项查询 与 match 查询,有个最大的区别,Term 词项查询时 ES 不会对检索内容进行分词,会将检索文本作为一个整体进行查询。而 match 查询会对检索内容做分词,然后对分词后的各个词项做查询。

使用如下:

复制代码
// 这样查到数据,因为基于文档的内容分词后,建立的倒排索引里,有"移动"、"联通"索引,但是没有"移动联通"这个索引
POST goods/_search
{
  "query": {
    "match": {
      "title": "移动联通"
    }
  }
}
// 这样查不到数据,因为基于文档的内容分词后,建立的倒排索引里,没有"移动联通"这个索引,因为term查询不分词。
POST goods/_search
{
  "query": {
    "term": {
      "title": {
        "value": "移动联通"
      }
    }
  }
}

5、总结

本文从 安装基本概念分词器 、*** 文档基本操作 *** 这 4 个方面带你快速入门 Elasticsearch。所有的文档在写入时,只要字段是text类型都会被分词,然后建立倒排索引。需要特别注意的点是:match 匹配查询会对查询文本做分词,Term 词项查询不会对查询文本做分词。

相关推荐
Elasticsearch2 小时前
如何使用 Agent Builder 排查 Kubernetes Pod 重启和 OOMKilled 事件
elasticsearch
jiayou642 小时前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤1 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
Elasticsearch1 天前
通用表达式语言 ( CEL ): CEL 输入如何改进 Elastic Agent 集成中的数据收集
elasticsearch
爱可生开源社区2 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1772 天前
《从零搭建NestJS项目》
数据库·typescript
加号33 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏3 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐3 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再3 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip