Elasticsearch入门指南

2,551 阅读10分钟

好好学习,天天向上

本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航

这篇文章主要是记录一下最近在学的Elasticsearch。没有什么复杂的原理,只是简单的使用。

简介

Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsearch 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。

环境搭建

这一小节主要介绍如何在docker下安装及配置Elasticsearch、IK分词器以及Kibana。

安装与配置Elasticsearch

我之所以选择在docker下安装是因为docker比较简单么,方便部署。怎么安装docker我就不说了,不知道的请自行百度。

docker pull elasticsearch:5.6.8  # 第一步肯定是要下载喽
# -d 后台运行 -i 交互式模式 9200外部访问端口http(Web管理平台端口) 9300容器端口tcp(服务默认端口)
# --name 给容器起个名字,这里叫elasticsearch
docker run -di --name=elasticsearch -p 9200:9200 -p 9300:9300 elasticsearch:5.6.8

在docker下安装就是这么简单,几行命令就搞定了。

可以看到,es可以正常访问了。但是光安装好还不行,从5.0版本开始es就默认关闭了远程连接,所以需要手动地开启远程连接。有可能我们会进行一些跨域的操作,所以还要进行跨域配置

docker exec -it elasticsearch /bin/bash  # 进入到elasticsearch容器中
cd config  # 切换到config目录下
# 如果使用vi命令时出现bash: vi: command not found的话,就安装一下vim
apt-get update
apt-get install vim
vi elasticsearch.yml # 编辑配置文件,冒号后面是有一个空格的

这个时候,由于虚拟机配置的问题,可能导致ES运行不起来,所以需要把系统参数调大一点。这一步是在虚拟机下操作的,不是在es容器中操作的,如果是在容器中,先输入exit命令退出容器。

vi /etc/security/limits.conf      # 编辑limits.conf文件,添加两行内容
vi /etc/sysctl.conf  # 编辑sysctl.conf文件,添加一行内容

OK!现在就可以了。

sysctl -p # 修改内核参数马上生效
docker update --restart=always elasticsearch  # 设置开机自启
docker restart elasticsearch    # 重启elasticsearch

安装IK分词器

Elasticsearch的标准分词器是不支持中文分词的。比如将“今天天气不错”进行分词,就会分成“今”,“天”,“天”,“气”,“不”,“错”。这显然是不对的,所以我们需要安装中文的分词器来支持中文。现在中文分词器用得最多的就是IK,那我们就来安装IK分词器。

从图中可以看出,5.x版本对应5.x版本的IK分词器。所以从github.com/medcl/elast…里面找到和ES相同版本的IK,下载下来

下载完成之后,通过SecureFX等软件传到虚拟机里面,当然也可以敲命令发送,只不过麻烦点,位置随意,我放在了root目录下。传过之后👇

yum install -y unzip zip           # 如果没有安装upzip的话就先安装
unzip elasticsearch-analysis-ik-5.6.8.zip   # 解压,解压后的文件夹名为elasticsearch
mv elasticsearch ik   # 为了方便辨认,重命名为ik,当然,不重命名或是命名为其它的也是可以的
# 安装ik的方式很简单,只要复制到es的plugins文件夹下即可
docker cp ./ik elasticsearch:/usr/share/elasticsearch/plugins
docker restart elasticsearch    # 重启elasticsearch

现在分词器已经正常工作了,图中指定的分词模式为“ik_max_word”,IK还为我们提供了另外一种分词模式“ik_smart”,这种相较于前者分词粒度粗一些,前者更细。但是有可能这两种分词模式的分词结果都不是我们想要的,就可以添加自定义的词库。

docker exec -it elasticsearch /bin/bash  # 进入到elasticsearch容器中
cd plugins/ik/config  # 切换到ik的配置目录下
vi IKAnalyzer.cfg.xml    # 编辑该文件

在这个文件中我们可以配置自定义词库以及停用词库。比如我们可以在my_dic.dic(在ik/config目录中)文件中添加分词

这样重启一下ES后就可以使用我们的自定义分词了。

Kibana

docker pull kibana:5.6.8   # 下载kibana的镜像
# 安装kibana
docker run -it -d -e ELASTICSEARCH_URL=http://192.168.31.168:9200 --name kibana --restart=always -p 5601:5601 kibana:5.6.8

然后通过http://192.168.31.168:5601就可以正常访问了。

基本概念

用过MySQL的都知道,我们是对表中的一行行数据进行增删查改操作,ES也是类似的,只不过我们是对文档进行增删查改操作。ES和MySQL的对应关系如下:

MySQL(数据库服务器) Elasticsearch(搜索引擎)
Databases(数据库) Indices(索引库)
Tables(表) Types(类型)
Rows(一行行的数据) Documents(文档)
Columns(字段) Fields(字段)
  • Index(索引)

Elasticsearch 数据管理的顶层单位就叫做索引,它是拥有几分相似特征的文档的集合。可以理解为MySQL中的数据库。

  • Type(类型)

Type是索引的一个逻辑分区,就是将一些字段组合起来标识为一个Type。比如姓名、学号、班级、年级可以组合成一个Type叫做student。相当于MySQL中的数据表。

  • Document(文档)

文档就是Index中真实存放数据的地方,是一个信息单元。比如user这个Type有姓名、年龄、号码这三个字段。那么“张三,25,18512345678”就是一个文档。相当于MySQL中数据表中的一条数据。

  • Field(字段)

字段就是属性名。比如id、name、title、phone_number等。是Type的组成单位。

  • 倒排索引

ES之所以能够实现快速,高效的搜索,是因为基于倒排索引的原理。如果我们想知道哪些网站有“腾讯老干妈”的新闻,在没有搜索引擎的帮助下我们只能一个网站一个网站找......这样拿着网站的网址(key)去找“腾讯老干妈”(value)的过程就叫做正排索引。但是平时我们百度一搜不就出来了吗。之所以我们可以这样做,是因为百度事先已经做好倒排索引了,就是把出现过“腾讯老干妈”的网站全部记录下来

腾讯 腾讯新闻,网易新闻,百度新闻,17173,哔哩哔哩...........
老干妈 腾讯新闻,网易新闻,百度新闻,豆果美食

我们搜索“腾讯老干妈”的时候,先分词,分成“腾讯”,“老干妈”,然后去倒排索引库里面查找出url,再求出交集返回给用户。这样拿着“腾讯老干妈”(value)去查找网站(key)的过程就叫做倒排索引。

基本操作

如果我们想操作ES,可以提供的Restful接口直接访问,也就是直接发送HTTP请求,或者是在kibana中使用DSL语句,这两种方式都是可以的。比如查询索引库

创建索引及Type

当安装好MySQL之后,我们需要在里面创建数据库,然后在数据库里面创建表,再为表添加一些字段,才可以使用。同样的,在ES中,先创建索引,然后再索引里面创建一个Type,Type里面再添加一些字段。

http://192.168.31.200:9200/user      # put请求 http://IP:Port/index_name
PUT /user           # DSL语句 PUT /index_name

使用上面两种方式都可以创建一个叫“user”的索引,但是现在索引里面还没有数据,相当于创建了数据库还没有创建表。所以现在来创建一个Type:

使用图中的方式就可以为user所以添加一个叫sutdent的Type,可以看到,使用HTTP或者DSL语句都是一样的,所以下面就不再演示HTTP请求的方式,只演示DSL。

当然,也可以在创建索引的同时添加一个或多个Type:

删除索引

DELETE index_name

添加文档

在MySQL中,我们添加数据是向表中添加一行行的数据,在ES中,这一条条的数据叫做Document。

POST index_name/type_name/document_id  # 这个document_id是文档的id不是id字段值
{
 json格式的数据
}

这样就成功添加了一条Document。

删除文档

DELETE index_name/type_name/document_id

修改文档

POST index_name/type_name/document_id

数据查询

和MySQL一样,查询的内容比增删改要多得多。

  • 查询所有数据
GET _search        # 查询所有索引中的数据
GET index_name/_search              # 查询一个索引下的所有数据
GET index_name/type_name/_search    # 查询一个索引下的一个Type下的所有数据
  • 根据id查询数据
GET index_name/type_name/document_id
  • 根据关键词查询

可以使用termtermsprefixmatchmulti_match对关键词进行限制

# term是精确查询,查询过程中不会对搜索词进行分词,所以搜索词必须是文档分词集合中的一个
GET _search             # 查询所有索引中的数据
或者  GET index_name/_search              # 查询一个索引下的所有数据
或者  GET index_name/type_name/_search    # 查询一个索引下的一个Type下的所有数据
{
  "query":{
    "term":{
      字段名:搜索词
    }
  }
}

# terms 允许多个Term,也不会分词
{
  "query":{
    "terms":{
      字段名:
        [
          字段值1,
          字段值2
        ]
    }
  }
}

#  prefix:前缀匹配,所有以特定搜索词开头的内容
GET _search
{
  "query": {
    "prefix": {
      字段名 : 搜索词
    }
  }
}

# match会对搜索词进行分词,然后对分词后的结果进行搜索
GET _search
{
  "query": {
    "match": {
      字段名: 搜索词
    }
  }
}

# multi_match查询允许你做match查询的基础上同时搜索多个字段
GET _search
{
  "query": {
    "multi_match": {
      "query": 搜索词,
      "fields": [
        字段1,
        字段2
        ……
      ]
    }
  }
}
  • 范围搜索range
#过滤-range 范围过滤
#gt表示> gte表示=>
#lt表示< lte表示<=
GET _search
{
  "query":{
    "range": {
      字段名: {
        "gte": 30,
        "lte": 57
      }
    }
  }
}
  • 查询哪些数据包含某个字段exists
GET _search
{
  "query": {
    "exists":{
      "field":要查询的字段名
    }
  }
}
  • 合并多个过滤条件查询结果的布尔逻辑bool
# must : 多个查询条件的完全匹配,相当于 and。
# must_not : 多个查询条件的相反匹配,相当于 not。
# should : 至少有一个查询条件匹配, 相当于 or。
GET _search
{
  "query": {
    "bool": {
      must/must_not/should: [
        {
          "term"……
        },
        {
          "range"……
        }
        ……
      ]
    }
  }
}
  • 对搜索结果排序sort
# 搜索排序
GET /user/_search
{
  "query":{
    …………
  },
  "sort":{
    字段名:{
      "order":"desc"    # asc升序 desc 降序
    }
  }
}
  • 对搜索结果分页
# 分页实现
# 从下标为N的数据开始查询
# size:每页显示条数
GET /user/_search
{
  "query":{
    …………
  },
  "from": 0,
  "size": 2
}

总结

这篇文章并没有提什么很深奥的东西,就是对Elasticsearch的使用做了一个总结,包括怎么搭建ES的环境,介绍了倒排索引等几个概念,对索引和数据的操作。我一直认为学一项技术,一开始不用去理解其中的原理,只有先用起来才能更好地理解这项技术。所以我后期的文章再对ES会做一个更详细的介绍。

如果我的文章对你有些帮助,不要忘了点赞,收藏,转发,关注。要是有什么好的意见欢迎在下方留言。让我们下期再见!

微信公众号
微信公众号