Elasticsearch 是一个准实时的分布式搜索分析引擎,提供索引、搜索和分析功能。 Logstash、xxBeats 是配套的数据导入工具,Kibana 提供了可视化页面。
学习资料: es官网文档、ElasticSearch Guide、ElasticSearch Apis
笔记列表:ElasticSearch
Index: es 中的 Document 的组织单位,每个 Document 都隶属一个 Index。
Mapping: index 中记录 Document 的每个 field 的数值类型等信息,影响 es 索引文档时的行为。
Document:一份序列化成 json 格式的文档数据,它由多个 field 组成,每个 field 是一个 key-value。
与关系型数据库类比:
关系型数据库 ES
----------------------------------------------------------------------------
管理的数据单元 包含多个列的关系型行记录 包含多个k-v field 的json 字符串
数据的组织单位 数据表 Index 索引
数据类型描述 建表语句 Index 的 Mapping
Table Index
Row Document
Column Field
Schema Mapping
SQL DSL
Document 的每个 field 可以使用不同的数据类型,es 根据 field 的类型使用不同的索引方式,例如:
Mapping 可以手动创建,或者启用 dynamic mapping, 让 es 自动添加并推断 field 的数据类型。
ES 的特点:
Es 检查运行状态:
curl http://127.0.0.1:9200
Index 创建时请求 body 中可以设置的内容分为 aliases、mappings 和 settings 三部分,Create index API。aliases 定义 index 的别名、mappings 定义 Document 中每个 field 的类型和配置,settings 定义 index 的存储副本以及其它 es 支持的功能,譬如分词。
创建 Index 并设置 Mapping:
PUT /my-index-000001?pretty
{
"mappings": {
"properties": {
"age": { "type": "integer" },
"email": { "type": "keyword" },
"name": { "type": "text" }
}
}
}
PUT 上传的内容就是 Mapping,age、email、name 是 Document 中的 field 名称,type 是 field 的数值类型。
DELETE /my-index-000001
PUT /test
{
"aliases": {
"alias_1": {},
"alias_2": {
"filter": {
"term": { "user.id": "kimchy" }
},
"routing": "shard-1"
}
}
}
文档:Mapping
mappings 可以在创建 index 时显式创建,也可以动态生成。动态模式下,es 自动将新发现的 field 添加到 mapping 中。
mappings 的配置参数在 API 文档中可以找到:Elastic Api->Index Apis->Create Index Api->Mapping Parameters。mapping 的配置参数有的作用于 mappings 自身,譬如 dynamic、properties,有的是作用于 properties 中的 field 例如下面的 copy_to。
PUT my-index-000001
{
"mappings": {
"dynamic": "false",
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text"
}
}
}
}
dynamic 表示是否自动更新 mapping。写入的文档中如果含有 mapping 中未定义的 fields ,行为取决于 dynamic 参数的值:
Dynamic 为 true: 自动创建一个 field 并推测出类型;
Dynamic 为 false: 写入成功,新增的字段不能被索引,只会出现在_source中;
Dynamic 为 strict:文档写入失败;
properties 中包含了对所有 field 的说明(以 field name 为 key)。properties 是 mapping 配置的主要部分,掌握 mapping 的关键是掌握 es 支持的 field data type 。每种 field data type 都有自己的适用参数,在 API 文档中可以找到:Elastic Api->Index Apis->Create Index Api->Field data types。适用于多种 field data type 的参数见 Mapping Parameters,注意其中有一些是适用于 mapping 的譬如 dynamic,结合目标 field data type 自身文档适用。
field data types 一旦定义后不能修改,如果要修改,必须用 Reindex API 重建索引。
mapping 的 fields 参数需要特别注意,通过它可以为一个 field 指定多种类型
。譬如下面的 city 是 text 类型,如果某些场合下 需要把 city 当作 keyword 类型处理,在 fields 中新增一个 keyworld 类型的 field,名字自定义。 下面的 city.raw 就会被作为 keyword 类型对待。
PUT my-index-000001
{
"mappings": {
"properties": {
"city": {
"type": "text", <-- 第一个类型 text
"fields": {
"raw": { <-- 在 fields 属性中设置一个使用其它类型的 field,名为 raw,类型为 keyword
"type": "keyword"
}
}
}
}
}
}
在一次查询中可以同时使用 city 和 city.raw:
GET my-index-000001/_search
{
"query": {
"match": {
"city": "york"
}
},
"sort": {
"city.raw": "asc"
},
"aggs": {
"Cities": {
"terms": {
"field": "city.raw"
}
}
}
}
mapping 的更多特性到 Mapping Parameters 中探索。
field 可以使用以下数据类型,不同版本的支持情况可能不同,详情见 Field data types:
数组类型不需要专门定义,每个 field 的数值都可以是一个数组列表。
常规类型:Common types
对象类型:Objects and relational types
结构化类型:Structured data types
聚合数据类型:Aggregate data types
搜索文本类型:Text Search types:
文档排名类型:Document ranking types:
地理位置类型:Spatial data types:
其它类型:Other types:
settings 中可以设置的内容较多,这里只简单说明,给出相关文档的链接。
PUT /my-index-000001 # 创建时设置 settings
{
"settings": {
"index": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
}
PUT /my-index-000001 # 可以省略 index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
PUT /test # 和 mappings 一起设置
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"properties": {
"field1": { "type": "text" }
}
}
}
settings 中和 Index 直接相关的配置有两类,分别是 static 和 dynamic 类型。static 类型的配置只能在创建 Index 的时候赋值,dynamic 类型的配置可以创建 Index 之后修改。在 Index Settings 中可以找到所有配置项目:
static:
index.number_of_shards
index.number_of_routing_shards
index.codec
index.routing_partition_size
index.soft_deletes.enabled
index.soft_deletes.retention_lease.period
index.load_fixed_bitset_filters_eagerly
index.shard.check_on_startup
dynamic:
index.number_of_replicas
index.auto_expand_replicas
index.search.idle.after
index.refresh_interval
index.max_result_window
index.max_inner_result_window
index.max_rescore_window
index.max_docvalue_fields_search
index.max_script_fields
index.max_ngram_diff
index.max_shingle_diff
index.max_refresh_listeners
index.analyze.max_token_count
index.highlight.max_analyzed_offset
index.max_terms_count
index.max_regex_length
index.query.default_field
index.routing.allocation.enable
index.routing.rebalance.enable
index.gc_deletes
index.default_pipeline
index.final_pipeline
index.hidden
特别注意,es 其它功能模块的设置也通过 settings 设置,settings_in_other_index_modules。比如分词配置 analysis。
创建 index 的时候指定分词规则:
PUT my-index-000001
{
"settings": {
"analysis": {
"analyzer": {
"std_folded": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"asciifolding"
]
}
}
}
},
"mappings": {
"properties": {
"my_text": {
"type": "text",
"analyzer": "std_folded" # 绑定分词器
}
}
}
}
使用 Index 的分词配置分词,注意用 GET 方法,body 中是要分词的内容:
GET my-index-000001/_analyze
{
"analyzer": "std_folded", # 方式一,指定分词器名称
"text": "Is this déjà vu?" # 目标文本
}
GET my-index-000001/_analyze
{
"field": "my_text", # 方式二,指定配置了分词器的 field
"text": "Is this déjà vu?" # 目标文本
}
分词结果:
{
"tokens": [
{
"token": "is",
"start_offset": 0,
"end_offset": 2,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "this",
"start_offset": 3,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "deja",
"start_offset": 8,
"end_offset": 12,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "vu",
"start_offset": 13,
"end_offset": 15,
"type": "<ALPHANUM>",
"position": 3
}
]
}
查看 es 中所有 index:
GET /_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .kibana-event-log-7.9.2-000001 BXulL2qmTTq2FYYOYdNqbQ 1 0 1 0 5.5kb 5.5kb
green open .apm-custom-link CS8LkfBvRKGdSXjI0ky6tw 1 0 0 0 208b 208b
green open .kibana_task_manager_1 569Jhi3NS8etY8pYF4jxvg 1 0 6 267 136.2kb 136.2kb
green open kibana_sample_data_ecommerce _6pu_ggDQCSLwL9jvrA-Fg 1 0 4675 0 4.7mb 4.7mb
green open .apm-agent-configuration t9t6VR2KQi-YDewFQjI0Fw 1 0 0 0 208b 208b
green open .kibana_1 pEI_2VXrTRagNq_fyWd5eg 1 0 75 1 12.6mb 12.6mb
yellow open my-index-000001 6mmUoVrASWSTBWQjKDicqg 1 1 0 0 208b 208b
查看 Index my-index-000001 的 Mapping:
GET /my-index-000001/_mapping
{
"my-index-000001" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "integer"
},
"email" : {
"type" : "keyword"
},
"name" : {
"type" : "text"
}
}
}
}
}
ES 支持在写入的 document 的时候自动创建不存在的 index:
PUT /new-index-000001/_doc/1
{
"age": 11,
"email": "[email protected]",
"name": "小王"
}
查看:
GET /new-index-000001/
Document 的写入分为 create、update、index 等几种方式。PUT 方法用于创建(Create)和重新索引(Index),POST 方法用于(Create)和更新(Update)。
my-index-000001 是目标 index,_doc
是 ES 定义的接口路径,1
是要写入的 Document 的 id,Body 是 Document 内容。
Create Document:PUT 需要指定文档 ID,如果ID已经存在则报错;POST 不指定 ID,由 ES 自动分配 ID。
# Create:PUT 方式需要指定ID,如果 ID 已经存在报错
PUT /my-index-000001/_create/1
PUT /my-index-000001/_doc/1?op_type=create # 另一种写法
{
"age": 11,
"email": "[email protected]",
"name": "小王"
}
# Create:POST 方式不需要指定,es 自动分配 ID
POST /my-index-000001/_doc
{
"age": 11,
"email": "[email protected]",
"name": "小王"
}
Index Document:PUT 方法,全量替换,会将 ID 对应的旧文档删除,然后新建并且 _version 增加 1。
# Index:PUT,指定 ID,不设置 op_type,_version+1
PUT /my-index-000001/_doc/1
{
"age": 11,
"email": "[email protected]",
"name": "小王"
}
Update Document:POST方式,使用 _update api,修改旧文档,_version 增加 1。
# Create:POST 方式不需要指定,es 自动分配 ID,_version+1
POST /my-index-000001/_update/1
{
"age": 12,
"email": "[email protected]",
"name": "小王"
}
向 _bulk 接口传入的 body 中,可以包括 create/update/index/delete 四种操作,单条失败不影响其它操作,返回每条的操作结果。
wget https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/src/test/resources/accounts.json
curl -H "Content-Type: application/json" -XPOST "localhost:9200/banke/_bulk?pretty&refresh" --data-binary "@accounts.json"
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"} }
查询 ID 为 1 的 Document:
GET /my-index-000001/_doc/1
{
"_index" : "my-index-000001",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"age" : 11,
"email" : "[email protected]",
"name" : "小王"
}
}
返回的结果中带 _
前缀 field 是 Document 的 Metadata fields。
_mget 接口支持一次请求包含多个查询:
GET /_mget
{
"docs" : [
{
"_index" : "test",
"_id" : "1"
},
{
"_index" : "test",
"_id" : "2"
}
]
}
```:
### Document Metadata fields
查询的 Document 的时候会发现,返回了很多带有 `_` 前缀的 field,它们是 es 内置的 metadata fields:
```sh
GET /my-index-000001/_doc/1
{
"_index" : "my-index-000001",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"age" : 11,
"email" : "[email protected]",
"name" : "小王"
}
}
其中 _version 是 Document 当前内容的版本,每修改一次加1,但是 es 只是给出了 _version 计数,不支持查询历史版本内容,How to retrieve older version document from elasticsearch?。
ES 支持的 Metadata fields ,不知道为啥没有包括返回的 _type、_version 等字段的说明,它们的含义需要到 Get Api 中查看。
found:
_type:
_seq_no:
_primary_term:
_index: 文档隶属的 Index
_id: 文档自身的 ID
_source:文档原始的 json 数据
_size: _source 中内容的大小,单位为字节
_doc_count:
_field_names:
_ignored:
_routing:
_meta:
_tier
查找年龄为 11 的 Document,使用 query 的 term 语句:
GET /my-index-000001/_search
{
"query": {
"term": {
"age": 11
}
}
}
数值匹配查找的结果是列表,hits.hits 是符合查询条件的文档列表,hits 中其它字段是对查询结果的说明:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "my-index-000001",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"age" : 11,
"email" : "[email protected]",
"name" : "小王"
}
}
]
}
}
_msearch 接口支持一次传入多个查询:
POST kibana_sample_data_ecommerce/_msearch
{}
{"query" : {"match_all" : {}},"size":1}
{"index" : "kibana_sample_data_flights"}
{"query" : {"match_all" : {}},"size":2}
DELETE /my-index-000001/_doc/1
{
"_index" : "my-index-000001",
"_type" : "_doc",
"_id" : "1",
"_version" : 6,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 1
}
查询已删除的文档:
GET /my-index-000001/_doc/1
{
"_index" : "my-index-000001",
"_type" : "_doc",
"_id" : "1",
"found" : false
}