27

ElasticSearch核心概念和文档的CRUD - 海向

 4 years ago
source link: https://www.cnblogs.com/haixiang/p/11181711.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.



本文所有命令均在 Kibana 的 dev tools 上进行

1. 基本概念

1.1 Node 与 Cluster

Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。单个 Elastic 实例称为一个节点(node)。一组节点构成一个集群(cluster)。

1.2 Index

Elastic 会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。所以,Elastic 数据管理的顶层单位就叫做 Index(索引)。它是单个数据库的同义词。每个 Index (即数据库)的名字必须是小写。

事实上,我们的数据被存储在分片(shards)中,索引只是一个把一个或多个分片分组在一起的逻辑空间。然而,这只是一些内部细节——我们的程序完全不用关心分片。对于我们的程序而言,文档存储在索引(index)中。剩下的细节由Elasticsearch关心既可。

可以使用如下命令,查询本节点下的所有索引

#查询所有索引
GET _cat/indices?v

可以得到以下结果

health status index     uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   idx5      Tzjr1CmGRlCOjZUyQ0QUhA   3   0          2            0      8.5kb          8.5kb
yellow open   idx4      z7zw83L9Tjyc1Fx7jb6l0A   1   1          3            1     11.8kb         11.8kb
green  open   idx2      7SSk77DkTN-VpUuXehgaDQ   3   0          7            2     27.2kb         27.2kb
yellow open   idx1      1bqxLckjSk-BZtERVNhPZQ   1   1          0            0       283b           283b
green  open   idx3      qc32ybYBT869QIPaYmcWGQ   3   0          0            0       849b           849b

你可能还注意到客户索引标记了黄色运行状况。黄色表示某些副本尚未分配。 此索引发生这种情况的原因是因为默认情况下Elasticsearch为此索引创建了一个副本。 由于我们目前只有一个节点在运行,因此在另一个节点加入集群的稍后时间点之前,尚无法分配一个副本(用于高可用性)。 将该副本分配到第二个节点后,此索引的运行状况将变为绿色。

创建索引(使用默认的设置)

PUT idx1/

创建索引同时指定节点的复制和分片数量

PUT idx2/
{
  "settings": {
    "index": {
        "number_of_shards" : "3",
        "number_of_replicas" : "0"
    }
  }
}

查询索引的基本信息

GET idx2/

获取所有索引的设置

GET _all/_settings
DELETE idx3/

1.3 Document

Index 里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。

Document 使用 JSON 格式表示,下面是一个例子。

{
  "_index" : "idx2",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 5,
  "_seq_no" : 5,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "BiologyBook2.0",
    "price" : 100.0
  }
}

同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。但是在 es6.0 后续版本中废除了 type,推荐所有的 Document 均默认使用 _doc 类型。

1.4 Type(将在ES6.0移除)

Document 可以分组,比如weather这个 Index 里面,可以按城市分组(北京和上海),也可以按气候分组(晴天和雨天)。这种分组就叫做 Type,它是虚拟的逻辑分组,用来过滤 Document。

2. 数据的增删改查

2.1 添加数据

在 es7.x 之后取消了 type,均使用_doc同一文档类型,想必之后版本连_doc也会被取消。

向指定的 /Index/Type 发送 PUT 请求,就可以在 Index 里面新增一条记录。比如,向/idx1/_doc发送请求,就可以新增一条人员记录。

POST /idx4/_doc/
{
  "name" : "anqi1.0",
  "age" : 20
}

我们会得到如下 json 结果,其中_id为该记录id,如果没指定的话 es 会帮我生成这种随机id,result为我们执行的操作,_index为所属索引

{
  "_index" : "idx4",
  "_type" : "_doc",
  "_id" : "0u8pvGsB-aEEelT0MVgW",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

我们也可以指定生成的id,这样的话得到的_id就为我们指定的数字1

POST /idx4/_doc/1
{
  "name" : "anqi1.0",
  "age" : 20
}

我们如果对不存在的文档执行更新操作,则会新增一条数据,

PUT /idx4/_doc/2
{
  "age" : 33
}

得到如下结果,当然我们不提倡统一索引下存放结构不一样的数据。(因为只有一个 age 属性)

{
  "_index" : "idx4",
  "_type" : "_doc",
  "_id" : "2",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

2.2 查询数据

根据id获取文档

GET /idx5/_doc/1

使用如下命令查询 idx5 索引下所有数据

GET /idx5/_search

得到如下结果, _source即为插入的数据

{
  "took" : 353,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {"value" : 2,"relation" : "eq"},
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "idx5",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "city" : "Yuanping",
          "email" : "[email protected]"
        }
      },
      {
        "_index" : "idx5",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "city" : "Xinzhou",
          "email" : "[email protected]"
        }
      }
    ]
  }
}

上面代码中,返回结果的 took字段表示该操作的耗时(单位为毫秒),timed_out字段表示是否超时,hits字段表示命中的记录,里面子字段的含义如下。

  • total:返回记录数,本例是2条。
  • max_score:最高的匹配程度,本例是1.0
  • hits:返回的记录组成的数组。

返回的记录中,每条记录都有一个_score字段,表示匹配的程序,默认是按照这个字段降序排列。

2.3 更新数据

更新数据就是发送 PUT请求,我们这里将id为1的数据中age属性更新为 22

PUT /idx4/_doc/1
{
  "age" : 22
}

更新后我们得到了以下结果

{
  "_index" : "idx4",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

可以看到,记录的 Id 没变,但是版本(version)从1变成2,操作类型(result)从created变成updated,因为这次不是新建记录

Elasticsearch是一个分布式系统。当documents被创建、更新或者删除,其新版本会被复制到集群的其它节点。Elasticsearch既是异步的(asynchronous )也是同步的(concurrent),其含义是复制请求都是并行发送的,但是到达目的地的顺序是无序的。Elasticsearch系统需要一种方法使得老版本的文档永远都无法覆盖新的版本。

每当文档被改变的时候,文档中的_version将会被增加(+1)。Elasticsearch使用_version确保所有的修改都会按照正确的顺序执行。如果文档旧的版本在新的版本之后到达,它会被简单的忽略。

2.4 删除数据

删除数据就是发送 DELETE 请求

DELETE /idx4/_doc/1

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK