Fork me on GitHub

ElasticSearch| 文档的CRUD

 

文档(Document)

Elasticsearch是面向文档的,文档是所有可搜索数据的最小单位

  •   日志文件中的日志项
  •   一本电影的具体信息/一张唱片的详细信息
  •   MP3播放器里的一首歌/一篇PDF文档中的具体内容

文档会被序列化成JSON格式,保存在Elasticsearch中

  • JSON对象由字段组成,
  • 每个字段都有对应的字段类型(字符串/数值/布尔/日期/二进制/范围类型)

每个文档都有一个UniqueID

  • 你可以自己指定ID
  • 或者通过Elasticsearch自动生成

 

 

JSON文档

一篇文档包含了一系列的字段, 类似数据库表中一条记录

JSON文档,格式灵活,不需要预先定义格式

  •     字段的类型可以指定或者通过Elasticsearch自动推算
  •     支持数组/支持嵌套
CSVfile 
----下来csvfile转换为json格式--->

movield, title, genres
1, ToyStory(1995), Adventure| AnimationIChildren| Comedy|Fantasy { "year":1995, "@version":"1", "genre":[ "Adventure","Animation', "ChiIdren","Comedy","Fantasy"], "id":"1", "title":"ToyStory" }

 

文档的元数据

  用于标注文档的相关信息

_index  文档所属的索引名
_type  文档所属的类型名
_id  文档唯一ID
_source:文档的原始Json数据
_all:  整合所有字段内容到该字段,已被废除
_version:文档的版本信息
_score:相关性打分

{
    "_index":"movies", 
    "_type":"_doc",
    "_id":"1",
    "_score":14.69302,
    "_source":{
        "year":1995,
        "@version":"1",
        "genre":[
            "Adventure",
            "Animation',
            "ChiIdren",
            "Comedy",
            "Fantasy"
        ],
        "id":"1",
        "title":"Toy Story"
    }
}

 

索引
"movies":{
    "settings":{
        "index":{
        "Creation_date":"1552737458543"
        "number_of_shards":"2",
        "number_of_replicas":"0",
        "uuid":"Qnd71MrNQPGdaeJ90RØtfQ"
        "version":{
        "created":"6@6@299"
        },
        "provided_name":"movtes"
        }
    }
}

Index 索引是文档的容器,是一类文档的结合

  •     Index体现了逻辑空间的概念:每个索引都有自己的Mapping定义,用于定义包含的文档的字段名和字段类型
  •     Shard体现了物理空间的概念:索引中的数据分散在Shard上

索引的Mapping与Settings

  •     Mapping定义文档字段的类型
  •     Setting定义不同的数据分布

 

 索引的不同语意

① 名词:一个Elasticsearch集群中,可以创建很多个不同的索引
② 动词:保存一个文档到Elasticsearch的过程也叫索引(indexing)

  •     ES中,创建一个倒排索引的过程

③ 名词:一个B树索引,一个倒排索引

 

 上图是 索引(动词)文档到Elasticsearch的索引(名词)中

 Type

PUT index 
{
    "mappings": {
        "properties":{ //Note how there is no toplevel key with the type name
            "@timestamp":{
              "type:"date"
            }
        }
    }
}


PUT index/_doc/1 //_doc becomes the new endpoint for document index,get and delete
requests {
    "@timestamp":"2020-02-10"
}

POST index/_bulk
{"index":{"_id":"2"}} //no _type in the URL or in document metadataRead More
{"@timestamp":"2019-03-01"}
{"update": {"_id": "1"}}
{"@timestamp": "2019-03-01"}

在7.0之前,一个Index可以设置多个Types

6.0开始,Type已经被Deprecated 7.0开始,一个索引只能创建一个Type "_doc"

抽象和类比

 

1. 在7.0之前,一个Index可以设置多个Types

2. 目前Type已经被Deprecated,7.0开始,索引只能创建一个Type: "_doc"

3. 传统关系型数据库和Elasticsearch的区别

  •     Elasticsearch - Schemaless/相关性/高

          性能全文检索

  •     RDMS - 事务性/Join

 REST APT  -- 很容易被各种语言调用

 

 一些基本的API

Indices

  ① 创建Index

    PUT Movies

  ②查看所有Index

     _cat/indices

 

节点、集群、分片及副本

分布式系统的可用性与扩展性
高可用性

  •     服务可用性 - 允许有节点停止服务
  •     数据可用性 - 部分节点丢失,不会丢失数据

可扩展性

  •     请求量提升/数据的不断增长(将数据分布到所有节点上)

 

分布式特性
Elasticsearch的分布式架构的好处

  •     存储的水平扩容
  •     提高系统的可用性,部分节点停止服务,整个集群的服务不受影响

Elasticsearch的分布式架构

  •     不同的集群通过不同的名字来区分,默认名字"elasticsearch"
  •     通过配置文件修改,或者在命令行中 - Ecluster.name=geektime进行设定
  •     一个集群可以有一个或者多个节点

节点

节点是一个Elasticsearch的实例

  • 本质上就是一个JAVA进程
  • 一台机器上可以运行多个Elasticsearch进程,但是生产环境一般建议一台机器上只运行一个Elasticsearch实例


每一个节点都有名字,通过配置文件配置,或者启动时候-E node.name=nodel指定

每一个节点在启动之后,会分配一个UID,保存在data目录下

Master—eligible nodes和Master Node

每个节点启动后,默认就是一个Master eligible节点

  • 可以设置 node.master:false 禁止

Master - eligible节点可以参加选主流程,成为Master节点

当第一个节点启动时候,它会将自己选举成Master节点

每个节点上都保存了集群的状态,只有Master节点才能修改集群的状态信息

   ① 集群状态(Cluster State),维护了一个集群中,必要的信息

  •  所有的节点信息
  •   所有的索引和其相关的Mapping与Setting信息
  •  分片的路由信息

   ② 任意节点都能修改信息会导致数据的不一致性

Data Node & Coordinating Node
DataNode

  •     可以保存数据的节点,叫做DataNode。负责保存分片数据。在数据扩展上起到了至关重要的作用

CoordinatingNode

  •     负责接受Client的请求,将请求分发到合适的节点,最终把结果汇集到一起
  •     每个节点默认都起到了Coordinating Node的职责

其他的节点类型
HOt&WarmNode

  •     不同硬件配置的Data Node,用来实现Hot&Warm架构,降低集群部署的成本

Machine Learning Node

  •     负责跑机器学习的Job,用来做异常检测

Tribe Node

  •     (5.3开始使用Cross Cluster Serarch) Tribe Node 连接到不同的Elasticsearch集群,
  •     并且支持将这些集群当成一个单独的集群处理

 配置节点类型

  •     开发环境中一个节点可以承担多种角色
  •     生产环境中,应该设置单一的角色的节点(dedicated node)

 

 分片(Primary Shard & Replica Shard)

主分片,用以解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内的所有节点之上

  •     一个分片是一个运行的Lucene的实例
  •     主分片数在索引创建时指定,后续不允许修改,除非 Reindex

副本,用以解决数据高可用的问题。分片是主分片的拷贝

  •     副本分片数,可以动态题调整
  •     增加副本数,还可以在一定程度上提高服务的可用性(读取的吞吐)

 

分片(Primary Shard & Replica Shard)

一个三节点的集群中,blogs索引的分片分布情况   

  思考:增加一个节点或改大主分片数对系统的影响?

 

 分片的设定

对于生产环境中分片的设定,需要提前做好容量规划
    分片数设置过小

  •   导致后续无法增加节点实现水品扩展
  •   单个分片的数据量太大,导致数据重新分配耗时

    分片数设置过大,7开始,默认主分片设置成1,解决了over-sharding的问题

  •   影响搜索结果的相关性打分,影响统计结果的准确性
  •   单个节点上过多的分片,会导致资源浪费,同时也会影响性能

查看集群健康状况

GET _cluster/health 
GET _cat/nodes //查看node的相关信息
GET _cat/shards //查看shards的相关信息

GET _cluster/health { "CIuster_name":"geektime", "status":"green", "timed_out":false, "number_of_nodes":2, //一共两个节点, "number_of_data_nodes":2, //这两个节点都承担了data node的角色 "active_primary_shards":37, //一共37个主分片 "active_shards":70, "relocating_shards":0, "initializing_shards":0, "unassigned_shards":0, "delayed_unassigned_shards":0, "number_of_pending—tasks":0, "number_of_in_flight_fetch":0, "task_max_waiting_in_queue_millis":0, "active_shards_percent_as_number":100.0 }

Green - 主分片与副本都正常分配

Yellow - 主分片全部正常分配,有副本分片未能正常分配

Red - 有主分片未能分配,例如当服务器的磁盘容量超过85%时,去创建了一个新的索引

 

 

文档的基本CRUD 

 

 

 

Create一个文档

支持自动生成文档ID和指定文档ID两种方式: 通过调用POST my_index/_doc/ 系统会自动生成ID 

使用HTTP PUT my_index/_doc/1/_create 创建时, URI中显示指定_create,  此时如果该id 的文档已经存在,则操作失败。

DELETE users
############Create Document############
#create document. 自动生成 _id : KS5tOXcBQn2iJa_jWk65
POST users/_doc
{
    "user" : "Mike",
    "post_date" : "2019-04-15T14:12:12",
    "message" : "trying out Kibana"
}

#create document. 指定Id。如果id已经存在,报错
PUT users/_doc/1?op_type=create
{
    "user" : "Jack",
    "post_date" : "2019-05-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

#create document. 指定 ID 如果已经存在,就报错
PUT users/_doc/1/_create
{
     "user" : "kris",
    "post_date" : "2019-05-15T14:12:12",
    "message" : "trying out Elasticsearch"
}
# "reason": "[_doc][1]: version conflict, document already exists (current version [1])",

Get 一个文档

       找到文档,返回HTTP 200
          文档元信息

      • _index/ _type/
      • 版本信息,同一个id的文档,即使被删除,Version号也会不断增加
      • _source中默认包含了文档的所有原始信息

        找不到文档,返回HTTP 404

### Get Document by ID
#Get the document by ID
GET users/_doc/1 

 

Index文档

Index和Create 不一样的地方:如果文档不存在,就索引新的文档。

否则现有文档会被删除,新的文档被索引。版本信息 +1 ;

即 PUT  my_index/_doc/1/_create ,如果文档存在会报错;

    PUT my_index/_doc/1 ,如果文档存在就先删除再index文档,_version加1 ;

update文档

# Update方法不会删除原来的文档,而是实现真正的数据更新
# Post方法 /Payload需要包含在"doc"
###  Index & Update
#Update 指定 ID  (先删除,在写入)
# 修改某个字段, updated, 会把之前的先删掉,再put,版本号+1
PUT users/_doc/1
{
    "user" : "Mike"
}
#查询得到, 之前的user、post_date、message被删除了
GET users/_doc/1

#GET users/_doc/1
#在原文档上增加字段, 不会删除重新put
POST users/_doc/1/_update
{
    "doc":{
        "post_date" : "2019-05-15T14:12:12",
        "message" : "trying out Elasticsearch"
    }
}

GET users/_doc/1

Bulk API

 

 

   

 

 

 

 常见错误返回

 

 

### Bulk 操作
#执行两次,查看每次的结果

#执行第1次
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test2", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }


#执行第2次
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test2", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

### mget 操作
GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_id" : "1"
        },
        {
            "_index" : "test",
            "_id" : "2"
        }
    ]
}


#URI中指定index
GET /test/_mget
{
    "docs" : [
        {

            "_id" : "1"
        },
        {

            "_id" : "2"
        }
    ]
}


GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_id" : "1",
            "_source" : false
        },
        {
            "_index" : "test",
            "_id" : "2",
            "_source" : ["field3", "field4"]
        },
        {
            "_index" : "test",
            "_id" : "3",
            "_source" : {
                "include": ["user"],
                "exclude": ["user.location"]
            }
        }
    ]
}

### msearch 操作
POST kibana_sample_data_ecommerce/_msearch
{}
{"query" : {"match_all" : {}},"size":1}
{"index" : "kibana_sample_data_flights"}
{"query" : {"match_all" : {}},"size":2}


### 清除测试数据
#清除数据
DELETE users
DELETE test
DELETE test2

 

posted @ 2021-01-25 23:46  kris12  阅读(108)  评论(0编辑  收藏  举报
levels of contents