Elasticsearch (ES)

Table of Contents

1. ES 简介

Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,它建立在全文搜索引擎 Apache Lucene(TM) 的基础上,提供了 REST API 的操作接口,开箱即用。 当然 Elasticsearch 并不仅仅是 Lucene 那么简单,它不仅包括了全文搜索功能,还可以进行以下工作:
1、分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索;
2、实时分析的分布式搜索引擎;
3、可以扩展到上百台服务器,处理 PB 级别的结构化或非结构化数据。

1.1. 安装和启动

下面是 Elasticsearch 的下载、安装和启动过程:

$ curl -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.5.4.tar.gz
$ tar -xvf elasticsearch-6.5.4.tar.gz
$ cd elasticsearch-6.5.4
$ ./bin/elasticsearch -d          # -d or --daemonize 表示以daemon形式运行
$ tail -f logs/elasticsearch.log  # 查看log

在 log 中如果发现下面警告:

[WARN ][o.e.b.BootstrapChecks    ] [QNKt1t1] max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

提示最大虚拟内存设置太小,使用下面命令可以临时调整最大虚拟内存大小:

$ sudo sysctl -w vm.max_map_count=262144

上面设置,在重启服务器后丢失,要永久生效,可以在文件“/etc/sysctl.conf”中增加下面这行:

vm.max_map_count=262144

默认,Elasticsearch 监听在地址“127.0.0.1:9200”上。 如果启动顺利,访问“127.0.0.1:9200”可以得到下面输出:

$ curl localhost:9200
{
  "name" : "lVd6G-p",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "2cBfxXbGRxWQZCHQ9PPR0w",
  "version" : {
    "number" : "6.5.4",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "d2ef93d",
    "build_date" : "2018-12-17T21:17:40.758843Z",
    "build_snapshot" : false,
    "lucene_version" : "7.5.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

2. ES 基本使用

2.1. ES 基本概念和 RDBMS 对比

Elasticsearch 将它的数据存储在一个或多个索引(index)中。文档(document)是 Elasticsearch 中的主要实体。对所有使用 Elasticsearch 的案例来说,他们最终都可以归结为对文档的搜索。文档由字段构成。

ES 基本概念和 RDBMS 对比如表 1 所示。

Table 1: ES 基本概念和 RDBMS 对比
RDBMS Elasticsearch
Database Index
Table Type(不推荐一个 Index 有多个 Type)
Row/Record Document
Column Field

2.2. 索引相关操作

2.2.1. 查看索引

通过下面 GET 请求可以查看服务器中存在的索引:

$ curl 'http://localhost:9200/_cat/indices?v'
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size

如果仅仅输出“health status index uuid pri rep docs.count docs.deleted store.size pri.store.size”则意味着目前系统中还没有索引。

2.2.2. 创建索引(PUT)

往服务器发送 PUT 请求可以新建索引,如下面例子创建名为 customer 的索引:

$ curl -X PUT "localhost:9200/customer?pretty"  # ?pretty是为了让json输出更好看
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "customer"
}

可以验证这个新创建的索引存在于系统中:

$ curl 'http://localhost:9200/_cat/indices?v'
health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   customer xncHNxw_SDWJhlHPAFdbew   5   1          0            0       631b           631b
                ^                                              ^
                |                                              |
             索引名称                                   索引中文档个数

注:一般地,我们不用特意地创建一个索引,当创建文档时,如果发现相应索引不存在系统会自动创建索引。后文会介绍如何创建文档。

2.2.3. 删除索引(DELETE)

往索引对应资源发送 DELETE 请求,可以删除索引,如删除名为 customer 的索引:

$ curl -X DELETE "localhost:9200/customer?pretty"
{
  "acknowledged" : true
}

2.3. 文档相关操作

文档相关操作的请求路径的格式为:

/INDEX/TYPE/Id

2.3.1. 增加文档(POST)

下面是增加文档的例子(索引为 customer,Type 为_doc,Id 为 1 的文档):

$ curl -X POST "localhost:9200/customer/_doc/1?pretty" -H 'Content-Type: application/json' -d'
{
  "name": "John Doe",
  "age": 28
}'
{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

上面命令中,明确指定了文档 Id 为 1,如果这个文档已存在,则会更新它。如果增加文档时不指定 Id,会自动生成 Id,如:

$ curl -X POST "localhost:9200/customer/_doc?pretty" -H 'Content-Type: application/json' -d'
{
  "name": "John De Hann",
  "age": 40
}'
{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "963cm2kBmzmcAGlmqz9M",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

上面例子中,没有明确指定 Id,自动生成的 Id 为“963cm2kBmzmcAGlmqz9M”。

2.3.2. 查看文档(GET)

下面是查看文档的例子(查看索引为 customer,Type 为_doc,Id 为 1 的文档):

$ curl "localhost:9200/customer/_doc/1?pretty"
{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "name" : "John Doe",
    "age" : 28
  }
}

2.3.3. 更新文档(POST 或者 PUT)

在介绍增加文档时,介绍了使用 POST(路径中指定 Id)可以更新文件。除此外,还可以使用 PUT 更新文档(更新索引为 customer,Type 为_doc,Id 为 1 的文档):

$ curl -X POST "localhost:9200/customer/_doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": { "name": "Jane Doe", "age": 20 }
}
'
{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

2.3.4. 删除文档(DELETE)

下面是删除文档的例子(删除索引为 customer,Type 为_doc,Id 为 1 的文档):

$ curl -X DELETE "localhost:9200/customer/_doc/1?pretty"
{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

2.4. 搜索文档

搜索文档的请求路径的格式为:

/INDEX/TYPE/_search

在介绍下面指令前,先删除之前的索引,并增加两条样例文档:

$ curl -X DELETE "localhost:9200/customer"

$ curl -X POST "localhost:9200/customer/_doc/1" -H 'Content-Type: application/json' -d'
{
  "name": "John Doe",
  "age": 28
}'

$ curl -X POST "localhost:9200/customer/_doc/2" -H 'Content-Type: application/json' -d'
{
  "name": "John De Hann",
  "age": 40
}'

2.4.1. 显示所有文档

不指定查询条件,直接发送 GET 到 /INDEX/TYPE/_search 即可查看所有文档,如查看索引为 customer,Type 为_doc 的文档:

$ curl "localhost:9200/customer/_doc/_search?pretty"
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "customer",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "John De Hann",
          "age" : 40
        }
      },
      {
        "_index" : "customer",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "John Doe",
          "age" : 28
        }
      }
    ]
  }
}

从输出中可见,返回了之前增加的 2 个文档。

2.4.2. 按条件搜索文档

Elasticsearch 的查询语法可参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/query-dsl.html

比如,要在索引为 customer,Type 为_doc 的文档中查找字段中包含“John”的文档,可以使用下面语法:

$ curl 'localhost:9200/customer/_doc/_search?pretty' -H 'Content-Type: application/json' -d '
{
  "query" : { "match" : { "name" : "John" }}
}'

上面请求的返回实例:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "customer",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "John De Hann",
          "age" : 40
        }
      },
      {
        "_index" : "customer",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "John Doe",
          "age" : 28
        }
      }
    ]
  }
}

3. Tips

3.1. 修改监听地址

默认,Elasticsearch 监听在地址“127.0.0.1:9200”上,只能从本机访问。可以通过修改文件“config/elasticsearch.yml”中下面两个配置来实现监听到其它地址的目的:

network.host: 0.0.0.0
http.port: 9200

Author: cig01

Created: <2018-09-17 Mon>

Last updated: <2019-04-21 Sun>

Creator: Emacs 27.1 (Org mode 9.4)