ElasticSearch-7.10 参考手册

2021-07-01 10:16:47 浏览数 (1)

1. ES参考手册

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

l 配置ES

1. Installing Elasticsearch

2. Configuring Elasticsearch

3. Important Elasticsearch configuration

4. Important System Configuration

5. Discovery and cluster formation

Kopf

l 段合并策略:

在段合并是,设置IO限流,防止影响磁盘IO indices.store.throttle.type

index.store.throttle.max_bytes_per_sec

l 多分片与多索引

多分片会对查询造成影响,最差情况是:查询被发往所有分片进行查询后,进行合并处理。

l 路由

根据路由键,使得ES决定使用哪个分片(shard)进行存储以及处理查询。

l 别名

可以为特定分片或者多个索引 设置别名,在查询时使用别名查询

l 热点线程

l 获取统计信息

curl ‘http://localhost:9999/_status?pretty’

2. ES 7.10版本新特性

l Data role

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/modules-node.html#node-roles

可以为节点配置 数据角色,

1.master

2.data

3.data_content 内容数据节点容纳用户创建的内容。它们支持CRUD、搜索和聚合等操作。

4.data_hot 存放经常查询和更新的数据

5.data_warm 存放查询频率相对比较少的查询和更新数据

6.data_cold 存放冷数据,很少被访问和更新的数据

7.ingest

8.remote_cluster_client

默认情况下,集群中的任何节点都可以充当跨集群客户机并连接到远程集群。连接后,可以使用跨群集搜索来搜索远程群集。您还可以使用跨群集复制在群集之间同步数据。

9.Coordinating only nodes

只处理请求和聚合结果,不存放数据

l 索引配置

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/index-modules.html#index-codec

静态配置项:

index.number_of_shards: 索引主分片数,在索引创建是指定,不可修改

index.number_of_routing_shards 在拆分索引分片时,指定shard的数量,可以参考https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-split-index.html

index.codec 指定压缩算法

index.routing_partition_size

index.soft_deletes.retention_lease.period

index.load_fixed_bitset_filters_eagerly

index.hidden

动态配置项:可以通过请求,动态更改配置

index.number_of_replicas

index.auto_expand_replicas

index.search.idle.after

index.refresh_interval

l point in time

保持搜索结果 的存活时间,

默认情况下,搜索请求在返回响应之前等待完整的结果。例如,检索热门点击和聚合的搜索仅在计算热门点击和聚合后返回响应。然而,聚合通常比热门搜索速度慢,计算成本高。可以发送两个单独的请求,而不是发送一个组合请求:一个用于热门点击,另一个用于聚合。对于单独的搜索请求,UI可以在最热门的搜索结果可用时立即显示它们,并在较慢的聚合请求完成后显示聚合数据。可以使用PIT来确保两个搜索请求在相同的数据和索引状态下运行。也就是说:防止由于数据集的更新,导致查询结果的不一致,使查询处于一致的数据集快照下。

l 索引线程池

system_read and system_write

3. 索引分片分配

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-allocation.html

l Shard allocation filtering: 分片分配过滤器

https://www.elastic.co/guide/en/elasticsearch/reference/current/shard-allocation-filtering.html

可以使用分片分配过滤器来控制Elasticsearch在何处分配特定索引的分片。每个过滤器需要与cluster-wide allocation filtering 和 allocation awareness 一起使用。

cluster-wide allocation filtering 和allocation awareness 可以参考一下地址:

目录结构:Set up Elasticsearch » Configuring Elasticsearch » Cluster-level shard allocation and routing settings

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-cluster.html#cluster-shard-allocation-filtering

大概讲的是:分片在什么情况下会被分配,主要由master负责。

allocation awareness :可以根据配置节点的机架和区域的属性,分配分片,防止 机具出现故障导致索引不可用。

在移动分片阶段,index 生命周期管理器可以根据node 的一些属性来决定怎样分配shard,node的属性包括:_name、_host、_ip、_id、 _tier、 _host_ip等

可以在elasticsearch.yml中配置,根据node 的大小 size 配置筛选条件 size :small|medium|big

代码语言:javascript复制
  node.attr.size: medium

也可以在启动节点的时候进行指定:

代码语言:javascript复制
`./bin/elasticsearch -Enode.attr.size=medium

向索引添加路由分配筛选器 ,可以使用include、exclude、 require. 设置

index.routing.allcotion.inclide|exclude|require.属性,例如:

代码语言:javascript复制
PUT test/_settings{
代码语言:javascript复制
  "index.routing.allocation.require.size": "big",
代码语言:javascript复制
  "index.routing.allocation.require.rack": "rack1"}

If any require type conditions are specified, all of them must be satisfied

If any exclude type conditions are specified, none of them may be satisfied

If any include type conditions are specified, at least one of them must be satisfied

l Delayed allocation:

当一个node 离开集群,就会触发master 执行重分配shard,过程如下:

1. 将节点中的主shard的副本 提升为主,

2. 将节点中的副本分片 重新 分配到其他节点(创建新的shard ,再复制 主分片)

3. 在所有的节点中,进行rebalance

整个过程会增加集群的负载,可以通过参数index.unassigned.node_left.delayed_timeout ,设置master 会等待多长时间,再执行上面的操作。

可以通过方式获取集群状态 delayed_unassigned_shards 表示延迟分配的shard:

代码语言:javascript复制
GET _cluster/health 

l Total shards per node:

index.routing.allocation.total_shards_per_node 设置索引在单个节点上的最大分片数,也就是同一个索引的主分片和副本分片,被分配到单个node上的数量。

cluster.routing.allocation.total_shards_per_node:每个节点分配分片的最大数量

l Data tier allocation:

可以控制,哪些索引分配在哪个数据层中,参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/data-tier-shard-filtering.html

4. mapper

定义 document 字段的映射类型

代码语言:javascript复制
PUT /my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "age":    { "type": "integer" },  
代码语言:javascript复制
      "email":  { "type": "keyword"  }, 
代码语言:javascript复制
      "name":   { "type": "text"  }     
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

太多的字段会导致mapper 爆炸,引起内存溢出问题,可以使用下面的配置,防止过多的mapper:

index.mapping.total_fields.limit:默认值是1000,

index.mapping.depth.limit: 嵌套field 映射,最大深度

index.mapping.nested_fields.limit: 最多嵌套数量

index.mapping.nested_objects.limit:json内部嵌套对象的最大数

index.mapping.field_name_length.limit: field的名称最大长度

动态映射:

在索引文档时,动态建立mapper,参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-mapping.html

Dynamic field mappings

Dynamic templates

查看mapper

代码语言:javascript复制
GET /my-index-000001/_mapping
代码语言:javascript复制
返回的数据:
代码语言:javascript复制
{
代码语言:javascript复制
  "my-index-000001" : {
代码语言:javascript复制
    "mappings" : {
代码语言:javascript复制
      "properties" : {
代码语言:javascript复制
        "age" : {
代码语言:javascript复制
          "type" : "integer"
代码语言:javascript复制
        },
代码语言:javascript复制
        "email" : {
代码语言:javascript复制
          "type" : "keyword"
代码语言:javascript复制
        },
代码语言:javascript复制
        "employee-id" : {
代码语言:javascript复制
          "type" : "keyword",
代码语言:javascript复制
          "index" : false
代码语言:javascript复制
        },
代码语言:javascript复制
        "name" : {
代码语言:javascript复制
          "type" : "text"
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

5. 段合并

Elasticsearch中的shard就是Lucene索引,Lucene索引被分解成若干段。段是不可变的。较小的段会定期合并为较大的段,合并期间会删除 被标记为删除的对象, 减少段的数量是有意的,会减少打开的文件句柄,同时查询索引会更快。

段合并有ConcurrentMergeScheduler 合并调度器管理,运行在不同的线程中,当段合并线程数达到最大值时,段合并就行等待合并线程可用,index.merge.scheduler.max_thread_count 设置最大线程数

6. 相关度

可以为不同的field 配置不同的相似度算法,

参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-similarity.html#index-modules-similarity

配置相关度:

代码语言:javascript复制
PUT /index{
代码语言:javascript复制
  "settings": {
代码语言:javascript复制
    "index": {
代码语言:javascript复制
      "similarity": {
代码语言:javascript复制
        "my_similarity": {   名称
代码语言:javascript复制
          "type": "DFR",      类型
代码语言:javascript复制
          "basic_model": "g",
代码语言:javascript复制
          "after_effect": "l",
代码语言:javascript复制
          "normalization": "h2",  正则化
代码语言:javascript复制
          "normalization.h2.c": "3.0"
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

设置 索引字段的相关度算法

代码语言:javascript复制
PUT /index/_mapping{
代码语言:javascript复制
  "properties" : {
代码语言:javascript复制
    "title" : { "type" : "text", "similarity" : "my_similarity" }
代码语言:javascript复制
  }}

常用的相关度算法:

l BM25:

基于TF/IDF 相似性的算法,内置TF 归一化,在短文本表现良好,例如 name;

选项:

k1:针对非线性词频 归一化 ,默认值 1.2

b:控制文档长度归一化系数

discount_overlaps:确定计算normalization 时是否忽略重叠标记

l DFR

l DFI

l IB

l LM Dirichlet

l LM Jelinek Mercer similarity .

7. 慢日志

l search的日志 是shard级别的日志

代码语言:javascript复制
index.search.slowlog.threshold.query.warn: 10s
代码语言:javascript复制
index.search.slowlog.threshold.query.info: 5s
代码语言:javascript复制
index.search.slowlog.threshold.query.debug: 2s
代码语言:javascript复制
index.search.slowlog.threshold.query.trace: 500ms
代码语言:javascript复制
index.search.slowlog.threshold.fetch.warn: 1s
代码语言:javascript复制
index.search.slowlog.threshold.fetch.info: 800ms
代码语言:javascript复制
index.search.slowlog.threshold.fetch.debug: 500ms
代码语言:javascript复制
index.search.slowlog.threshold.fetch.trace: 200ms
代码语言:javascript复制
index.search.slowlog.level: info

可以通过更新操作修改慢日志配置:如下

代码语言:javascript复制
PUT /my-index-000001/_settings{
代码语言:javascript复制
  "index.search.slowlog.threshold.query.warn": "10s",
代码语言:javascript复制
  "index.search.slowlog.threshold.query.info": "5s",
代码语言:javascript复制
  "index.search.slowlog.threshold.query.debug": "2s",
代码语言:javascript复制
  "index.search.slowlog.threshold.query.trace": "500ms",
代码语言:javascript复制
  "index.search.slowlog.threshold.fetch.warn": "1s",
代码语言:javascript复制
  "index.search.slowlog.threshold.fetch.info": "800ms",
代码语言:javascript复制
  "index.search.slowlog.threshold.fetch.debug": "500ms",
代码语言:javascript复制
  "index.search.slowlog.threshold.fetch.trace": "200ms",
代码语言:javascript复制
  "index.search.slowlog.level": "info"}

日志记录是在shard级别的范围内完成的,这意味着在特定shard中执行搜索请求。它不包含整个搜索请求。shard级日志记录的一些好处是,与请求级日志记录相比,将特定计算机上的实际执行关联起来。

在请求时,通过在header中设置X-Opaque-ID 值,当发生慢查询时,该值会被一起记录在慢日志文件中,这样可以方便了解是什么触发了慢查询。

代码语言:javascript复制
[2030-08-30T11:59:37,786][WARN ][i.s.s.query] [node-0] [index6][0] took[78.4micros], took_millis[0], total_hits[0 hits], stats[], search_type[QUERY_THEN_FETCH], total_shards[1], source[{"query":{"match_all":{"boost":1.0}}}], id[MY_USER_ID],

l index级别的慢日志

代码语言:javascript复制
index.indexing.slowlog.threshold.index.warn: 10s
代码语言:javascript复制
index.indexing.slowlog.threshold.index.info: 5s
代码语言:javascript复制
index.indexing.slowlog.threshold.index.debug: 2s
代码语言:javascript复制
index.indexing.slowlog.threshold.index.trace: 500ms
代码语言:javascript复制
index.indexing.slowlog.level: info
代码语言:javascript复制
index.indexing.slowlog.source: 1000

8. 存储

ES会基于当前的操作系统,选择最好的存储实现,包括:fs、simplefs、niofs、mmapfs、hybridfs

可以通过在elasticsearch.yml中配置:

代码语言:javascript复制
index.store.type: hybridfs
代码语言:javascript复制
针对索引进行设置:
代码语言:javascript复制
PUT /my-index-000001{
代码语言:javascript复制
  "settings": {
代码语言:javascript复制
    "index.store.type": "hybridfs"
代码语言:javascript复制
  }}

mmapfs:基于MMap,虚拟地址映射,实现了零拷贝,提高读取速度

hybridfs : 是基于nio 和 mmap的混合实现,它根据读取访问模式为每种类型的文件选择最佳的文件系统类型

可以通过 node.store.allow_mmap 设置是够允许使用 mmap和hybrid,值为boolean类型

9. TransLog 事务日志

将更新数据刷写到索引中的代价很大,无法对每个单独的更改执行,因此每个shard副本还将操作写入其事务日志translog中。所有的索引和删除操作在被内部索引处理之后但在它们被确认之前被写入translog。在崩溃的情况下,当shard恢复时,可以从translog中恢复。

执行flush操作会提交索引数据,以及创建新的translog文件。刷新是在后台自动执行的,以确保translog不会增长太大,这将使重放其操作在恢复过程中花费相当长的时间。通过API进行手动执行刷新,尽管这很少需要。

只有当translog被fsynced和committed时,translog中的数据才会持久化到磁盘。在发生硬件故障、操作系统崩溃、JVM崩溃或碎片故障时,自上次translog提交以来写入的任何数据都将丢失。

将index.translog.durability设置为request 表示 es在事务日志提交成功后,才会返回客户端成功的消息,如果 将 index.translog.durability 设置为async ,表示 Es在处理请求后会立即返回操作成功的消息,事务日志通过后台同步线程,周期性的刷写到磁盘上,如果遇到崩溃会导致数据丢失。

可以通过以下配置来控制索引的事务日志:

index.translog.sync_interval 刷写事务日志到磁盘的时间间隔,默认 5s ,不能低于100ms

index.translog.durability 持久化方式,request 表示在每次请求后都会执行 fsync 和

commit,保证事务日志不丢失。 async 表示 fsync 和commit 操作会在后台线程中周期性的执行,

index.translog.flush_threshold_size,为了避免事务日志回放时间过长,通过设置该值来控制事务日志的大小,默认值是500M

注:translog retention 机制已经在 7.4 废除。

10. Index sort

参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-index-sorting.html

在创建索引是指定 排序规则,可以指定排序的field

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "settings": {
代码语言:javascript复制
    "index": {
代码语言:javascript复制
      "sort.field": "date", 
代码语言:javascript复制
      "sort.order": "desc"  
代码语言:javascript复制
    }
代码语言:javascript复制
  },
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "date": {
代码语言:javascript复制
        "type": "date"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

注意:索引排序和嵌套字段不兼容,如果要使用排序则该field不能是嵌套的field

可以对多个field 设置排序

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "settings": {
代码语言:javascript复制
    "index": {
代码语言:javascript复制
      "sort.field": [ "username", "date" ], 
代码语言:javascript复制
      "sort.order": [ "asc", "desc" ]       
代码语言:javascript复制
    }
代码语言:javascript复制
  },
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "username": {
代码语言:javascript复制
        "type": "keyword",
代码语言:javascript复制
        "doc_values": true
代码语言:javascript复制
      },
代码语言:javascript复制
      "date": {
代码语言:javascript复制
        "type": "date"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

index.sort.field 用于排序的field 列表,类型只能是boolean, numeric, date , keyword

index.sort.order:排序规则定义,asc、desc

index.sort.mode:当field字段中有多个值时,需要选择哪个值用于排序,minmax

index.sort.missing missing参数指定应如何处理缺少该字段的文档。 _last_first

默认情况下,在Elasticsearch中,搜索请求必须访问与查询匹配的每个文档,以检索按指定排序 排序的top文档。当索引排序和搜索排序相同时,可以限制每个段应访问的文档数,以便全局检索N个排名靠前的文档。

11. Mapping

参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html#removal-of-types

ES 7.0 以后的版本不在支持 _default_ mapping

在es中,在同一个索引中,索引多个不同类型文档时,其相同field的类型应该是相同,如果引起field字段类型冲突,可以将两个冲突类型的文档放入到不同的索引中。与关系型数据库类比:index 类似 数据库,type 类似 表,document 类似 表记录,但是 在关系型数据库中表的列的名称是独立的,但是在index 中,type中的field 是相关的,重名的field需要有相同的类型。

l 定制type field

一个集群中可以primary shard是有限制的,为了不浪费主分片数。可以实现自己的自定义类型字段,使用 user 和 tweet 为例:

代码语言:javascript复制
PUT twitter{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "user": {     #定义了一个type 为 user的 类型
代码语言:javascript复制
      "properties": {   # user 属性值
代码语言:javascript复制
        "name": { "type": "text" },  
代码语言:javascript复制
        "user_name": { "type": "keyword" },
代码语言:javascript复制
        "email": { "type": "keyword" }
代码语言:javascript复制
      }
代码语言:javascript复制
    },
代码语言:javascript复制
    "tweet": {
代码语言:javascript复制
      "properties": {
代码语言:javascript复制
        "content": { "type": "text" },
代码语言:javascript复制
        "user_name": { "type": "keyword" },
代码语言:javascript复制
        "tweeted_at": { "type": "date" }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT twitter/user/kimchy{
代码语言:javascript复制
  "name": "Shay Banon",
代码语言:javascript复制
  "user_name": "kimchy",
代码语言:javascript复制
  "email": "shay@kimchy.com"}
代码语言:javascript复制
PUT twitter/tweet/1{
代码语言:javascript复制
  "user_name": "kimchy",
代码语言:javascript复制
  "tweeted_at": "2017-10-24T09:00:00Z",
代码语言:javascript复制
  "content": "Types are going away"}
代码语言:javascript复制
GET twitter/tweet/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "match": {
代码语言:javascript复制
      "user_name": "kimchy"
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

可以通过添加自定义类型字段来实现相同的功能,如下

代码语言:javascript复制
PUT twitter{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "_doc": {
代码语言:javascript复制
      "properties": {
代码语言:javascript复制
        "type": { "type": "keyword" }, 
代码语言:javascript复制
        "name": { "type": "text" },
代码语言:javascript复制
        "user_name": { "type": "keyword" },
代码语言:javascript复制
        "email": { "type": "keyword" },
代码语言:javascript复制
        "content": { "type": "text" },
代码语言:javascript复制
        "tweeted_at": { "type": "date" }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT twitter/_doc/user-kimchy{
代码语言:javascript复制
  "type": "user", 
代码语言:javascript复制
  "name": "Shay Banon",
代码语言:javascript复制
  "user_name": "kimchy",
代码语言:javascript复制
  "email": "shay@kimchy.com"}
代码语言:javascript复制
PUT twitter/_doc/tweet-1{
代码语言:javascript复制
  "type": "tweet", 
代码语言:javascript复制
  "user_name": "kimchy",
代码语言:javascript复制
  "tweeted_at": "2017-10-24T09:00:00Z",
代码语言:javascript复制
  "content": "Types are going away"}
代码语言:javascript复制
GET twitter/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "bool": {
代码语言:javascript复制
      "must": {
代码语言:javascript复制
        "match": {
代码语言:javascript复制
          "user_name": "kimchy"
代码语言:javascript复制
        }
代码语言:javascript复制
      },
代码语言:javascript复制
      "filter": {
代码语言:javascript复制
        "match": {
代码语言:javascript复制
          "type": "tweet" 
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

ES7.0 关于mapping 使用的改变:

1. 在请求中不用指定type,例如: put {index}/_doc/{id}

2. include_type_name 默认设置false,已不再使用

3. _default_ 被移除

l 迁移多类型的索引到单个类型的索引中

代码语言:javascript复制
PUT users{
代码语言:javascript复制
  "settings": {
代码语言:javascript复制
    "index.mapping.single_type": true
代码语言:javascript复制
  },
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "_doc": {
代码语言:javascript复制
      "properties": {
代码语言:javascript复制
        "name": {
代码语言:javascript复制
          "type": "text"
代码语言:javascript复制
        },
代码语言:javascript复制
        "user_name": {
代码语言:javascript复制
          "type": "keyword"
代码语言:javascript复制
        },
代码语言:javascript复制
        "email": {
代码语言:javascript复制
          "type": "keyword"
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT tweets{
代码语言:javascript复制
  "settings": {
代码语言:javascript复制
    "index.mapping.single_type": true
代码语言:javascript复制
  },
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "_doc": {
代码语言:javascript复制
      "properties": {
代码语言:javascript复制
        "content": {
代码语言:javascript复制
          "type": "text"
代码语言:javascript复制
        },
代码语言:javascript复制
        "user_name": {
代码语言:javascript复制
          "type": "keyword"
代码语言:javascript复制
        },
代码语言:javascript复制
        "tweeted_at": {
代码语言:javascript复制
          "type": "date"
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
POST _reindex{
代码语言:javascript复制
  "source": {
代码语言:javascript复制
    "index": "twitter",
代码语言:javascript复制
    "type": "user"
代码语言:javascript复制
  },
代码语言:javascript复制
  "dest": {
代码语言:javascript复制
    "index": "users",
代码语言:javascript复制
    "type": "_doc"
代码语言:javascript复制
  }}
代码语言:javascript复制
POST _reindex{
代码语言:javascript复制
  "source": {
代码语言:javascript复制
    "index": "twitter",
代码语言:javascript复制
    "type": "tweet"
代码语言:javascript复制
  },
代码语言:javascript复制
  "dest": {
代码语言:javascript复制
    "index": "tweets",
代码语言:javascript复制
    "type": "_doc"
代码语言:javascript复制
  }}

自定义type 的field

代码语言:javascript复制
PUT new_twitter{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "_doc": {    # _doc 是类型
代码语言:javascript复制
      "properties": {
代码语言:javascript复制
        "type": {
代码语言:javascript复制
          "type": "keyword"
代码语言:javascript复制
        },
代码语言:javascript复制
        "name": {
代码语言:javascript复制
          "type": "text"
代码语言:javascript复制
        },
代码语言:javascript复制
        "user_name": {
代码语言:javascript复制
          "type": "keyword"
代码语言:javascript复制
        },
代码语言:javascript复制
        "email": {
代码语言:javascript复制
          "type": "keyword"
代码语言:javascript复制
        },
代码语言:javascript复制
        "content": {
代码语言:javascript复制
          "type": "text"
代码语言:javascript复制
        },
代码语言:javascript复制
        "tweeted_at": {
代码语言:javascript复制
          "type": "date"
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
POST _reindex{
代码语言:javascript复制
  "source": {
代码语言:javascript复制
    "index": "twitter"
代码语言:javascript复制
  },
代码语言:javascript复制
  "dest": {
代码语言:javascript复制
    "index": "new_twitter"
代码语言:javascript复制
  },
代码语言:javascript复制
  "script": {
代码语言:javascript复制
    "source": """
代码语言:javascript复制
      ctx._source.type = ctx._type;
代码语言:javascript复制
      ctx._id = ctx._type   '-'   ctx._id;
代码语言:javascript复制
      ctx._type = '_doc';
代码语言:javascript复制
    """
代码语言:javascript复制
  }}

l document Api 文档api

Ø 保存文档

代码语言:javascript复制
PUT /my-index-000001/_doc/1
代码语言:javascript复制
{"foo": "baz"}
代码语言:javascript复制
# 返回数据
代码语言:javascript复制
{
代码语言:javascript复制
  "_index": "my-index-000001",
代码语言:javascript复制
  "_id": "1",
代码语言:javascript复制
  "_type": "_doc",
代码语言:javascript复制
  "_version": 1,
代码语言:javascript复制
  "result": "created",
代码语言:javascript复制
  "_shards": {
代码语言:javascript复制
    "total": 2,
代码语言:javascript复制
    "successful": 1,
代码语言:javascript复制
    "failed": 0
代码语言:javascript复制
  },
代码语言:javascript复制
  "_seq_no": 0,
代码语言:javascript复制
  "_primary_term": 1}

Ø 查询 和 删除 操作使用路径 {index}/_doc/{id}

path部分可以在索引后紧跟 endpoint name 例如_update

代码语言:javascript复制
POST /my-index-000001/_update/1{
代码语言:javascript复制
  "doc" : {
代码语言:javascript复制
    "foo" : "qux"
代码语言:javascript复制
  }}
代码语言:javascript复制
GET /my-index-000001/_source/1

Ø 搜索Api

当调用search API时,例如 _search,_msearch ,_explain,types 不应该包含在路径中,另外,_type 字段不应该在queryaggregationscripts 中使用

在文档和搜索 api 中将继续返回 _type field,以防止响应被终止,但在8.0版本中,将被移除。

Ø 索引模板

代码语言:javascript复制
PUT _template/template1{
代码语言:javascript复制
  "index_patterns":[ "index-1-*" ],
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "foo": {
代码语言:javascript复制
        "type": "keyword"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
 PUT index-1-01?include_type_name=true{ # 会继承 模板template1 中定义的属性 foo
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "type": {
代码语言:javascript复制
      "properties": {
代码语言:javascript复制
        "bar": {
代码语言:javascript复制
          "type": "long"
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

Ø field 字段类型

数据类型汇总表:

对象相关的类型

object,flattened,nested,join

结构化数据类型:

Range,ip,version,murmur3

聚合数据类型

aggregate_metric_double、histogram

文本搜索类型

text、annotated-text、completion、search_as_you_type、token_count

文档排名类型

dense_vector、sparse_vector、rank_feature、rank_features

空间数据类型

geo_point、geo_shape、point、shape

数组类型

arrays

多字段类型

fields

参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html#_core_datatypes

binary(二进制)、boolean、Keywords(关键词)、Numbers(数值),Dates(日期),

v alias(别名)类型

代码语言:javascript复制
# 别名
代码语言:javascript复制
PUT trips{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "distance": {
代码语言:javascript复制
        "type": "long"
代码语言:javascript复制
      },
代码语言:javascript复制
      "route_length_miles": {
代码语言:javascript复制
        "type": "alias",
代码语言:javascript复制
        "path": "distance"   # path 指定field,如果是嵌套对象,需要使用全路径 objecta.objectb.aa
代码语言:javascript复制
      },
代码语言:javascript复制
      "transit_mode": {
代码语言:javascript复制
        "type": "keyword"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
GET _search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "range" : {
代码语言:javascript复制
      "route_length_miles" : {
代码语言:javascript复制
        "gte" : 39
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

别名的限制:

1.目标必须是具体的字段,而不是对象或其他字段别名。并且只能对应一个字段,不能对应多个

2.在创建别名时,字段field必须同时存在

3.如果定义了嵌套对象,字段别名必须与其目标具有相同的嵌套范围

4.不能应用在索引和更新api上

v object(jsonObject) 类型

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": { 
代码语言:javascript复制
      "region": {
代码语言:javascript复制
        "type": "keyword"
代码语言:javascript复制
      },
代码语言:javascript复制
      "manager": { 
代码语言:javascript复制
        "properties": {
代码语言:javascript复制
          "age":  { "type": "integer" },
代码语言:javascript复制
          "name": { 
代码语言:javascript复制
            "properties": {
代码语言:javascript复制
              "first": { "type": "text" },
代码语言:javascript复制
              "last":  { "type": "text" }
代码语言:javascript复制
            }
代码语言:javascript复制
          }
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
 PUT my-index-000001/_doc/1{ 
代码语言:javascript复制
  "region": "US",
代码语言:javascript复制
  "manager": { 
代码语言:javascript复制
    "age":     30,
代码语言:javascript复制
    "name": { 
代码语言:javascript复制
      "first": "John",
代码语言:javascript复制
      "last":  "Smith"
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
索引后结构为:
代码语言:javascript复制
{
代码语言:javascript复制
  "region":             "US",
代码语言:javascript复制
  "manager.age":        30,
代码语言:javascript复制
  "manager.name.first": "John",
代码语言:javascript复制
  "manager.name.last":  "Smith"
代码语言:javascript复制
}

v flattened(将整个JSON对象作为单个字段值。)

将整个json对象解析出其字段的值作为关键词,并设置为文档的字段值,在索引期间不会对value 值进行分析和特殊的处理例如日期,这样json对象就可以被搜索和聚合。该数据类型适合 存在大量未知键的JSON对象,通过映射到一个field上,来防止字段暴躁。

flattened 类型不支持数据范围查询以及高亮,同时不能索引整个文档内容且不支持全文搜索,

支持的查询:

1) term, terms, and terms_set

2) prefix

3) range

4) match and multi_match

5) query_string and simple_query_string

6) exists

代码语言:javascript复制
#flattened
代码语言:javascript复制
PUT bug_reports{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "title": {
代码语言:javascript复制
        "type": "text"
代码语言:javascript复制
      },
代码语言:javascript复制
      "labels": {
代码语言:javascript复制
        "type": "flattened"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
POST bug_reports/_doc/1{
代码语言:javascript复制
  "title": "Results are not sorted correctly.",
代码语言:javascript复制
  "labels": {
代码语言:javascript复制
    "priority": "urgent",
代码语言:javascript复制
    "release": ["v1.2.5", "v1.3.0"],
代码语言:javascript复制
    "timestamp": {
代码语言:javascript复制
      "created": 1541458026,
代码语言:javascript复制
      "closed": 1541457010
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
# 查询指定json 的key
代码语言:javascript复制
POST bug_reports/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "term": {"labels.release": "v1.3.0"}
代码语言:javascript复制
  }}

mapping 字段时,可设置以下参数:

# boost 用于提升查询权重,默认值为1。相关度

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "title": {
代码语言:javascript复制
        "type": "text",
代码语言:javascript复制
        "boost": 2    # 标识 title 是 content 权重的2倍,
代码语言:javascript复制
      },
代码语言:javascript复制
      "content": {
代码语言:javascript复制
        "type": "text"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

# depth_limit 默认值是20,允许json嵌套的深度

# doc_values:是一种数据存储结构,是以面向列的一种存储方式,将相同的列放在一

起存放,支持大部分数据类型,除了text和 annotated_text

# eager_global_ordinals

参考:

https://www.elastic.co/guide/en/elasticsearch/reference/current/eager-global-ordinals.html

global ordinals:根据词汇表顺序为每个词指定一个递增整数或序数,doc values中存放

是 序数 而不是 词本身,查询时进行 词与 序数的转换。

每个索引段定义自己的顺序映射,但聚合会跨整个shard收集数据。因此,为了能够将序号用于聚合之类的分片级操作,Elasticsearch创建了一个全局序号的统一映射。全局序数映射是建立在segment段序数之上的,为每个segment段维护一个从全局序数到局部序数的映射。

global ordinals 是会被存放在内存中进行缓存,是 field data cache的一部分. 应用于一下情况:

1. 在keyword,ip,和flattened field 使用bucket 聚合,包括 terms

2. join 操作

3. 在text field 上开启了 fielddata,能够对text field字段进行分析,并进行索引

如果启用了 global ordinals,则在刷新shard时会生成global ordinals , Elasticsearch总是在将更改同步到索引之前加载它们。这将把构建global ordinals的成本从搜索时间转移到索引时间。Elasticsearch在创建shard的新副本时也会构建全局序号,当增加副本数量或将shard重新定位到新节点时也会出现这种情况。

eager_global_ordinals 不能用在冻结的索引上

通常情况下, global ordinals 在内存和加载时间上不会带来巨大的开销,但是,当索引有大量的shard时,或者字段field 中保存大量的词时,就会带来开销,因为 global ordinals是为每个segment 建立映射关系,当新创建一个segment时,就会重建整个 global ordinals

#ignore_above 超过该参数的字段,不会被索引。在put 数据的时候,如果 字段的数

据超过了该参数值,不会被索引

#index 是否被索引,只有被索引的字段才能被搜索

#index_options 有哪些信息存放到索引中用于计算分数,默认是文档数 docs ,可以指

定词频 freqs

#null_value null值是否能被搜索到

代码语言:javascript复制
#定义一个能搜索到null值的索引
代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "status_code": {
代码语言:javascript复制
        "type":       "keyword",
代码语言:javascript复制
        "null_value": "NULL" 
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
#放入一个文档,值为null
代码语言:javascript复制
PUT my-index-000001/_doc/1
代码语言:javascript复制
{"status_code": null}
代码语言:javascript复制
#检索null值的文档
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "term": {
代码语言:javascript复制
      "status_code": "NULL" 
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

#similarity 设置相关度算法,参考 6 相关度 一节

# split_queries_on_whitespace 在全文查询时,是否需要通过 whitespace 分隔词项来为字段构建查询

v nested(json 嵌套)

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": { 
代码语言:javascript复制
      "group": {
代码语言:javascript复制
        "type": "keyword"
代码语言:javascript复制
      },
代码语言:javascript复制
      "user": { 
代码语言:javascript复制
        "properties": {
代码语言:javascript复制
              "first": { "type": "array" },
代码语言:javascript复制
              "last":  { "type": "array" }
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
以下是类型为Object 
代码语言:javascript复制
PUT my-index-000001/_doc/1{
代码语言:javascript复制
  "group" : "fans",
代码语言:javascript复制
  "user" : [ 
代码语言:javascript复制
    {
代码语言:javascript复制
      "first" : "John",
代码语言:javascript复制
      "last" :  "Smith"
代码语言:javascript复制
    },
代码语言:javascript复制
    {
代码语言:javascript复制
      "first" : "Alice",
代码语言:javascript复制
      "last" :  "White"
代码语言:javascript复制
    }
代码语言:javascript复制
  ]}
代码语言:javascript复制
索引后的结构为
代码语言:javascript复制
{
代码语言:javascript复制
  "group" :        "fans",
代码语言:javascript复制
  "user.first" : [ "alice", "john" ],
代码语言:javascript复制
  "user.last" :  [ "smith", "white" ]}
代码语言:javascript复制
以下查询是搜索不到数据的
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "bool": {
代码语言:javascript复制
      "must": [
代码语言:javascript复制
        { "match": { "user.first": "Alice" }},
代码语言:javascript复制
        { "match": { "user.last":  "Smith" }}
代码语言:javascript复制
      ]
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

下面使用嵌套类型,来保持数组内的对象的关系,替换掉 object 类型

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "user": {
代码语言:javascript复制
        "type": "nested"   # 使用嵌套类型,代替 object类型
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{
代码语言:javascript复制
  "group" : "fans",
代码语言:javascript复制
  "user" : [
代码语言:javascript复制
    {
代码语言:javascript复制
      "first" : "John",
代码语言:javascript复制
      "last" :  "Smith"
代码语言:javascript复制
    },
代码语言:javascript复制
    {
代码语言:javascript复制
      "first" : "Alice",
代码语言:javascript复制
      "last" :  "White"
代码语言:javascript复制
    }
代码语言:javascript复制
  ]}
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "nested": {
代码语言:javascript复制
      "path": "user",
代码语言:javascript复制
      "query": {
代码语言:javascript复制
        "bool": {
代码语言:javascript复制
          "must": [
代码语言:javascript复制
            { "match": { "user.first": "Alice" }},  #不会匹配到数据,没有在同一个嵌套对象内
代码语言:javascript复制
            { "match": { "user.last":  "Smith" }} 
代码语言:javascript复制
          ]
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "nested": {
代码语言:javascript复制
      "path": "user",
代码语言:javascript复制
      "query": {
代码语言:javascript复制
        "bool": {
代码语言:javascript复制
          "must": [
代码语言:javascript复制
            { "match": { "user.first": "Alice" }}, #可以匹配到数据,因为在同一个嵌套对象内
代码语言:javascript复制
            { "match": { "user.last":  "White" }} 
代码语言:javascript复制
          ]
代码语言:javascript复制
        }
代码语言:javascript复制
      },
代码语言:javascript复制
      "inner_hits": { 
代码语言:javascript复制
        "highlight": {  #高亮显示
代码语言:javascript复制
          "fields": {
代码语言:javascript复制
            "user.first": {}
代码语言:javascript复制
          }
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

每一个嵌套的object 作为单独的Lucene 文档 被索引,例如上面的例子,如果索引一个文档包含100个user 对象,则会创建101个文档,其中一个父文档,100个user嵌套文档,

可以通过以下设置,限制 嵌套对象:

index.mapping.nested_fields.limit 指定嵌套字段的个数,默认50个

index.mapping.nested_objects.limit 嵌套对象的个数 默认10000

v Join 类型

使用join的场景是 一对多的关系时。

一个索引只允许一个join 映射的字段

父|子文档 必须索引在相同的分片内

一个文档中,只能有一个父,可以有多个子 元素

join查询性能比较低,很少建议使用

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "my_id": {
代码语言:javascript复制
        "type": "keyword"
代码语言:javascript复制
      },
代码语言:javascript复制
      "my_join_field": {   # 定义join类型字段
代码语言:javascript复制
        "type": "join",
代码语言:javascript复制
        "relations": {
代码语言:javascript复制
          "question": "answer"  # 定义关系,question 是 answer的父字段
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
---------------------------------------
代码语言:javascript复制
 # 保存两个文档
代码语言:javascript复制
PUT my-index-000001/_doc/1?refresh{
代码语言:javascript复制
  "my_id": "1",
代码语言:javascript复制
  "text": "This is a question",
代码语言:javascript复制
  "my_join_field": {  # 指定这是哪个字段
代码语言:javascript复制
    "name": "question" 
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/2?refresh{
代码语言:javascript复制
  "my_id": "2",
代码语言:javascript复制
  "text": "This is another question",
代码语言:javascript复制
  "my_join_field": {
代码语言:javascript复制
    "name": "question"
代码语言:javascript复制
  }}
代码语言:javascript复制
------------------------------
代码语言:javascript复制
保存 子关联的字段
代码语言:javascript复制
PUT my-index-000001/_doc/3?routing=1&refresh {  # 使用routing 确保父子在同一个分片内
代码语言:javascript复制
  "my_id": "3",
代码语言:javascript复制
  "text": "This is an answer",
代码语言:javascript复制
  "my_join_field": {    #指定字段,以及父id
代码语言:javascript复制
    "name": "answer", 
代码语言:javascript复制
    "parent": "1" 
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/4?routing=1&refresh{
代码语言:javascript复制
  "my_id": "4",
代码语言:javascript复制
  "text": "This is another answer",
代码语言:javascript复制
  "my_join_field": {
代码语言:javascript复制
    "name": "answer",
代码语言:javascript复制
    "parent": "1"
代码语言:javascript复制
  }}
代码语言:javascript复制
-----------------------------------------
代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "my_join_field": {
代码语言:javascript复制
        "type": "join",
代码语言:javascript复制
        "relations": {   # 多层级 join 
代码语言:javascript复制
          "question": ["answer", "comment"],  
代码语言:javascript复制
          "answer": "vote" 
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

v Range field types

主要用于聚合,例如 直方图。支持integer_range、float_range、long_range、double_range、date_range、ip_range

代码语言:javascript复制
PUT range_index{
代码语言:javascript复制
  "settings": {
代码语言:javascript复制
    "number_of_shards": 2
代码语言:javascript复制
  },
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "expected_attendees": {   # 定义一个integer_range
代码语言:javascript复制
        "type": "integer_range"
代码语言:javascript复制
      },
代码语言:javascript复制
      "time_frame": {   # 定义一个日期类型范围的字段
代码语言:javascript复制
        "type": "date_range", 
代码语言:javascript复制
        "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
代码语言:javascript复制
      }                                              
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
------------------------------------------
代码语言:javascript复制
PUT range_index/_doc/1?refresh{
代码语言:javascript复制
  "expected_attendees" : { 
代码语言:javascript复制
    "gte" : 10,
代码语言:javascript复制
    "lt" : 20
代码语言:javascript复制
  },
代码语言:javascript复制
  "time_frame" : {
代码语言:javascript复制
    "gte" : "2015-10-31 12:00:00", 
代码语言:javascript复制
    "lte" : "2015-11-01"
代码语言:javascript复制
  }
代码语言:javascript复制
------------------------------------------
代码语言:javascript复制
 # 搜索 数据
代码语言:javascript复制
GET range_index/_search{
代码语言:javascript复制
  "query" : {
代码语言:javascript复制
    "term" : {
代码语言:javascript复制
      "expected_attendees" : {
代码语言:javascript复制
        "value": 12
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
#搜索日期范围的数据
代码语言:javascript复制
GET range_index/_search{
代码语言:javascript复制
  "query" : {
代码语言:javascript复制
    "range" : {
代码语言:javascript复制
      "time_frame" : { 
代码语言:javascript复制
        "gte" : "2015-10-31",
代码语言:javascript复制
        "lte" : "2015-11-01",
代码语言:javascript复制
        "relation" : "within" 
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
------------------------------------------
代码语言:javascript复制
# 定义IP范围类型的字段
代码语言:javascript复制
PUT range_index/_mapping{
代码语言:javascript复制
  "properties": {
代码语言:javascript复制
    "ip_allowlist": {
代码语言:javascript复制
      "type": "ip_range"
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT range_index/_doc/2{
代码语言:javascript复制
  "ip_allowlist" : "192.168.0.0/16"}

v version field type

版本号类型,是一种特殊的keyword 类型;用于软件的版本号,

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "my_version": {
代码语言:javascript复制
        "type": "version"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

v murmur

在索引期间,mapper-murmur3 插件可以计算 字段值的hash并存储在索引中,这样针对在高基数和大字符串字段上进行基数聚合是有帮助的

代码语言:javascript复制
 # 安装 插件,需要在每个node上进行安装,以
代码语言:javascript复制
sudo bin/elasticsearch-plugin install mapper-murmur3

v histogram field type

需要提供一对数组,且两个数组的长度必须相等:

第一个:double 类型的数组,代表的是直方图的bucket,

第二个:integer 类型的数组,表示bucket中的值的数量

histogram 类型的字段不支持排序,也不支持嵌套的数组,该类型的字段不会被索引,只会存储,字节大小最多是:13*numvalues,numvalues数组的长度。

只能使用一下聚合和查询:

l min aggregation

l max aggregation

l sum aggregation

l value_count aggregation

l avg aggregation

l percentiles aggregation

l percentile ranks aggregation

l boxplot aggregation

l histogram aggregation

l exists query

直方图的两种模式:

1. T-Digest

参考地址:

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-aggregation.html

代码语言:javascript复制
GET latency/_search{
代码语言:javascript复制
  "size": 0,
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "percentiles": {
代码语言:javascript复制
        "field": "load_time"  # load_time 表示系统加载时间,统计系统加载时间
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
 # percentiles 默认百分比例 [ 1, 5, 25, 50, 75, 95, 99 ]
代码语言:javascript复制
GET latency/_search{
代码语言:javascript复制
  "size": 0,
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "percentiles": {
代码语言:javascript复制
        "field": "load_time",
代码语言:javascript复制
        "percents": [ 95, 99, 99.9 ]  #指定percentiles 的百分比例范围值
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

keyed 标签可以设置 查询聚合返回值的数据格式,默认是true,会为每个bucket生成唯一的字符串key,如下:

代码语言:javascript复制
{
代码语言:javascript复制
  ...
代码语言:javascript复制
 "aggregations": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "values": {
代码语言:javascript复制
        "1.0": 5.0,
代码语言:javascript复制
        "5.0": 25.0,
代码语言:javascript复制
        "25.0": 165.0,
代码语言:javascript复制
        "50.0": 445.0,
代码语言:javascript复制
        "75.0": 725.0,
代码语言:javascript复制
        "95.0": 945.0,
代码语言:javascript复制
        "99.0": 985.0
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

当keyed 设置为false 后,返回值如下:

代码语言:javascript复制
GET latency/_search{
代码语言:javascript复制
  "size": 0,
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "percentiles": {
代码语言:javascript复制
        "field": "load_time",
代码语言:javascript复制
        "keyed": false
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
---------------------------------------------
代码语言:javascript复制
{
代码语言:javascript复制
  ...
代码语言:javascript复制
  "aggregations": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "values": [
代码语言:javascript复制
        {
代码语言:javascript复制
          "key": 90.0,
代码语言:javascript复制
          "value": 5.0
代码语言:javascript复制
        },
代码语言:javascript复制
        {
代码语言:javascript复制
          "key": 95.0,
代码语言:javascript复制
          "value": 945.0
代码语言:javascript复制
        },
代码语言:javascript复制
        {
代码语言:javascript复制
          "key": 99.0,
代码语言:javascript复制
          "value": 985.0
代码语言:javascript复制
        }
代码语言:javascript复制
      ]
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

在查询中使用脚本,改变数据统计

代码语言:javascript复制
GET latency/_search{
代码语言:javascript复制
  "size": 0,
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "percentiles": {
代码语言:javascript复制
        "script": {   # 将field 字段替换为 script 
代码语言:javascript复制
          "lang": "painless",
代码语言:javascript复制
          "source": "doc['load_time'].value / params.timeUnit", # 取出 文档中的load_time 字段 然
代码语言:javascript复制
                                                            后除以 timeUnit
代码语言:javascript复制
          "params": {    # 指定参数
代码语言:javascript复制
            "timeUnit": 1000                                    
代码语言:javascript复制
          }
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
 # 指定自定义的脚本
代码语言:javascript复制
GET latency/_search{
代码语言:javascript复制
  "size": 0,
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "percentiles": {
代码语言:javascript复制
        "script": {
代码语言:javascript复制
          "id": "my_script",  # 指定脚本
代码语言:javascript复制
          "params": {
代码语言:javascript复制
            "field": "load_time"
代码语言:javascript复制
          }
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

正确率与q(1-q) 成正比,

小的数据集有更高的精确度

随着bucket中值的数量增加,算法开始逼近百分位数。它有效地用精确性换取内存节省。精确取决于数据分布和聚合的数据量,也就将某一数值放入对应的桶内,在聚合计算时,使用bucket 的值代替,计算近似值,这样可以节省大量的内存。在机器学习领域得到大量的使用。

代码语言:javascript复制
GET latency/_search{
代码语言:javascript复制
  "size": 0,
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "percentiles": {
代码语言:javascript复制
        "field": "load_time",
代码语言:javascript复制
        "tdigest": {
代码语言:javascript复制
          "compression": 200     # 指定压缩比例,默认100
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

TDigest 算法中,越多的bucket 计算的精确度就越高,compression 参数控制着 bucket的最大数量:20*compression,提高compression的值可以提高精确度

2.High Dynamic Range Histogram

HDR 算法在计算速度和内存使用作出权衡,计算速度比T-Digest 快,只支持正数值,不能有负值

代码语言:javascript复制
GET latency/_search{
代码语言:javascript复制
  "size": 0,
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "load_time_outlier": {
代码语言:javascript复制
      "percentiles": {
代码语言:javascript复制
        "field": "load_time",
代码语言:javascript复制
        "percents": [ 95, 99, 99.9 ],
代码语言:javascript复制
        "hdr": {      # 表明使用 HDR 算法                               
代码语言:javascript复制
          "number_of_significant_value_digits": 3   #指定计算精度
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
GET latency/_search{
代码语言:javascript复制
  "size": 0,
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "grade_percentiles": {
代码语言:javascript复制
      "percentiles": {
代码语言:javascript复制
        "field": "grade",
代码语言:javascript复制
        "missing": 10        # 指定默认值
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

v Text 类型

该类型可以被分析器进行分析,经过分词器、过滤器 形成多个terms,该数据类型不能用于排序以及很少用于聚合操作。如果想索引 结构化的内容时,例如 email,主机名,状态码,标签等,可以使用keyword 类型,而不该使用 text 类型。

有时需要同时使用 text 和 keyword 类型,一个用于索引搜索,一个用于聚合和排序,此时可以使用 multi-fields ,参考 multi-fields 一节,

参数:

analyzer

配置分析器

boost

用于为查询结果配置权重

Fielddata

该参数默认值 false,设置为true后,会将字段的值通过 倒排索引 加载到内存,这样会占用大量的内存,在需要聚合和排序的text类型的字段,使用fielddata 是唯一可以访问tokens的方法,通常使用 mutil-field 替代 fielddata

fielddata_frequency_filter

可以过滤不必要的数据到内存中

eager_global_ordinals

参考上面的章节

fields

参考  multi-fields

index

boolean 类型,设置为true,需要被索引

index_options

设置索引时的配置项: docs -索引文档的数量 freqs -词频,文档数和词频被索引 positions -文档数、词频、词所在位置被索引 offsets - Doc number, term frequencies, positions, and start and end character offsets  词在文档的偏移量

index_prefixes

词的开头多少字符可被索引,前缀 min_chars 设置最小前缀字符数 max_chars 设置最大前缀字符数

index_phrases

设置为true,两个词可以合并 并被索引到单独的字段中,这样可以实现精确 词语的查询,前提是更大的索引为代价,如果不删除停用词这种方式效果最好,因为包含停用词不会使用附属字段,并且回退到标准短语查询

norms

用于计算评分的正则化因子,正则化需要更多的磁盘空间,如果不需要计算评分,则设置为false,通常情况下,norms 用于 filter和aggregations

position_increment_gap

默认值为100,为具有多个值的文本字段在索引时,会在值之间添加一个虚拟间距,以防止大多数短语查询跨值匹配。 https://www.elastic.co/guide/en/elasticsearch/reference/current/position-increment-gap.html

store

设置为true,保存字段值,字段的值被索引以便查询,但是原始的值并没有被存储,但 _source 字段存放了字段的值,可以使用 source filter 过滤要查询的字段。

search_analyzer

设置查询分析器,建议和analyzer 保持一致,如果是非短语查询会移除停用词

search_quote_analyzer

在短语查询时,不会移除停用词

similarity

设置相近度算法

term_vector

词向量包括以下数据: 1. terms 集合 2. 每个词位置 3. 词在源数据中的起止位置 4. payloads 保存了与每个词位置相关用户定义的二进制数据 参数值: no - 不存储词向量 yes - 仅存储 terms with_positions - 词和位置被存储 with_offsets - 词和偏移量 被存储 with_positions_offsets  存储 词、位置、偏移量 with_positions_payloads 存储 词、位置 和 payload with_positions_offsets_payloads 存储 词 位置 偏移量 payload

v multi-fields

如果在同一个字段上有不同的使用目的,此时可以使用 multi-field 字段。也可以对现有的字段进行修改,使用 PUT api,multi-field 不会改变原始的源字段

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "city": {
代码语言:javascript复制
        "type": "text",  # text 类型,用于搜索
代码语言:javascript复制
        "fields": {  # 定义多类型的字段
代码语言:javascript复制
          "raw": {    # city.raw 用于 排序和聚合
代码语言:javascript复制
            "type":  "keyword"
代码语言:javascript复制
          }
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{
代码语言:javascript复制
  "city": "New York"}
代码语言:javascript复制
PUT my-index-000001/_doc/2{
代码语言:javascript复制
  "city": "York"}
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "match": {
代码语言:javascript复制
      "city": "york" 
代码语言:javascript复制
    }
代码语言:javascript复制
  },
代码语言:javascript复制
  "sort": {
代码语言:javascript复制
    "city.raw": "asc"    # 用于排序
代码语言:javascript复制
  },
代码语言:javascript复制
  "aggs": {
代码语言:javascript复制
    "Cities": {
代码语言:javascript复制
      "terms": {
代码语言:javascript复制
        "field": "city.raw"   # 用于聚合
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

使用multi-field 可以在同一个字段上使用不同的分析器,如下:

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "text": { 
代码语言:javascript复制
        "type": "text",
代码语言:javascript复制
        "fields": {
代码语言:javascript复制
          "english": { 
代码语言:javascript复制
            "type":     "text",
代码语言:javascript复制
            "analyzer": "english"
代码语言:javascript复制
          }
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{ "text": "quick brown fox" } 
代码语言:javascript复制
PUT my-index-000001/_doc/2{ "text": "quick brown foxes" } 
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "multi_match": {
代码语言:javascript复制
      "query": "quick brown foxes",
代码语言:javascript复制
      "fields": [ 
代码语言:javascript复制
        "text",
代码语言:javascript复制
        "text.english"
代码语言:javascript复制
      ],
代码语言:javascript复制
      "type": "most_fields" 
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

v search_as_you_type

联想查询,通过创建一系列的子字段来索引 词项,这样对于通过部分匹配(partially matches ) 去匹配整个索引值的查询来说是有效的。

目前存在两种:

1. prefix completion 输入词前缀匹配

2. infix completion 匹配输入词在文本中的任意位置

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "my_field": {
代码语言:javascript复制
        "type": "search_as_you_type"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

会创建一下字段:

my_field

my_field._2gram

使用2元gram进行分词

my_field._3gram

使用3元gram进行分词

my_field._index_prefix

使用edge gram进行分词操作,前缀匹配

N-gram中的N可以通过mapping中设置 max_shingle_size 参数进行控制,存放整型数据,默认值是3,可接受范围是[2,4],其中._index_prefix 会一直存在。增大 max_shingle_size 会提高更多连续值的匹配效率,代价是带来更多的索引存储。

代码语言:javascript复制
 # 会自动在每个字段中对 上面的 文本进行索引
代码语言:javascript复制
PUT my-index-000001/_doc/1?refresh{
代码语言:javascript复制
  "my_field": "quick brown fox jump lazy dog"}
代码语言:javascript复制
#查询
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "multi_match": {
代码语言:javascript复制
      "query": "brown f",
代码语言:javascript复制
      "type": "bool_prefix",
代码语言:javascript复制
      "fields": [
代码语言:javascript复制
        "my_field",
代码语言:javascript复制
        "my_field._2gram",
代码语言:javascript复制
        "my_field._3gram"
代码语言:javascript复制
      ]
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
# 结果
代码语言:javascript复制
{
代码语言:javascript复制
  "took" : 44,
代码语言:javascript复制
  "timed_out" : false,
代码语言:javascript复制
  "_shards" : {
代码语言:javascript复制
    "total" : 1,
代码语言:javascript复制
    "successful" : 1,
代码语言:javascript复制
    "skipped" : 0,
代码语言:javascript复制
    "failed" : 0
代码语言:javascript复制
  },
代码语言:javascript复制
  "hits" : {
代码语言:javascript复制
    "total" : {
代码语言:javascript复制
      "value" : 1,
代码语言:javascript复制
      "relation" : "eq"
代码语言:javascript复制
    },
代码语言:javascript复制
    "max_score" : 0.8630463,
代码语言:javascript复制
    "hits" : [
代码语言:javascript复制
      {
代码语言:javascript复制
        "_index" : "my-index-000001",
代码语言:javascript复制
        "_type" : "_doc",
代码语言:javascript复制
        "_id" : "1",
代码语言:javascript复制
        "_score" : 0.8630463,
代码语言:javascript复制
        "_source" : {
代码语言:javascript复制
          "my_field" : "quick brown fox jump lazy dog"
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    ]
代码语言:javascript复制
  }}

按照查询词query trems的顺序进行严格匹配,或使用短语查询的其他属性进行搜索,可以在root filed 中使用 match_phrase_prefix ,也可以使用match_phrase 如果最后的词进行了完全匹配且没有作为前缀,使用短语查询比 match_bool_prefix 查询效率低。

代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "match_phrase_prefix": {
代码语言:javascript复制
      "my_field": "brown f"
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

analyzer

指定索引期间和搜索期间的分词器

index

是否进行索引 true 或 false

index_options

文本索引的粒度,支持 docs、freqs、positions、offsets

norms

true 或 false;存储该字段归一化因子,如果字段不需要参与评分

store

是否独立存储field数据

search_analyzer

查询时分词器

search_quote_analyzer

默认使用 search_analyzer

similarity

指定相似度算法

term_vector

是否存储term向量

v token count

用于定义索引字段 词的个数。如下:

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "name": { 
代码语言:javascript复制
        "type": "text",
代码语言:javascript复制
        "fields": {
代码语言:javascript复制
          "length": { 
代码语言:javascript复制
            "type":     "token_count",   # 定义分词的个数
代码语言:javascript复制
            "analyzer": "standard"
代码语言:javascript复制
          }
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{ "name": "John Smith" }  # 分词数是2
代码语言:javascript复制
PUT my-index-000001/_doc/2{ "name": "Rachel Alice Williams" }  # 分词数是 3
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "term": {
代码语言:javascript复制
      "name.length": 3   # 只匹配分词 个数是 3 的记录
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

v dense-vector 密集词向量

存放的是浮点值,向量中的值的维度最大不能超过2048,在内部 dense_vector 类型的数据会编码为二进制数据进行保存, 字节大小为 4*dims 4

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "my_vector": {
代码语言:javascript复制
        "type": "dense_vector",
代码语言:javascript复制
        "dims": 3     # 声明 向量中值的数量
代码语言:javascript复制
      },
代码语言:javascript复制
      "my_text" : {
代码语言:javascript复制
        "type" : "keyword"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{
代码语言:javascript复制
  "my_text" : "text1",
代码语言:javascript复制
  "my_vector" : [0.5, 10, 6]}
代码语言:javascript复制
PUT my-index-000001/_doc/2{
代码语言:javascript复制
  "my_text" : "text2",
代码语言:javascript复制
  "my_vector" : [-0.5, 10, 10]}

v sparse vector 稀疏向量

稀疏词向量中的数值维度不能超过1024,字节大小:6 * NUMBER_OF_DIMENSIONS 4

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "my_vector": {
代码语言:javascript复制
        "type": "sparse_vector"
代码语言:javascript复制
      },
代码语言:javascript复制
      "my_text" : {
代码语言:javascript复制
        "type" : "keyword"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{
代码语言:javascript复制
  "my_text" : "text1",
代码语言:javascript复制
  "my_vector" : {"1": 0.5, "5": -0.5,  "100": 1}}
代码语言:javascript复制
PUT my-index-000001/_doc/2{
代码语言:javascript复制
  "my_text" : "text2",
代码语言:javascript复制
  "my_vector" : {"103": 0.5, "4": -0.5,  "5": 1, "11" : 1.2}}

v rank feature

使用该数据类型,可以在后续的查询中提升文档的排名。(使用rank query)

仅支持单值字段,值必须是正数

只能配合 rank query使用,不支持其他查询、排序和聚合

保留了9个有效位,相对误差约为0.4%

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "pagerank": {
代码语言:javascript复制
        "type": "rank_feature" 
代码语言:javascript复制
      },
代码语言:javascript复制
      "url_length": {
代码语言:javascript复制
        "type": "rank_feature",
代码语言:javascript复制
        "positive_score_impact": false  # 与得分负相关的排名 需要声明,rank feature查询将使用它来修改评分公式,使评分随特征值的增加而减少,而不是增加。例如在web搜索中,url长度是一个常用的特征,它与得分呈负相关。
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{
代码语言:javascript复制
  "pagerank": 8,
代码语言:javascript复制
  "url_length": 22}
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "rank_feature": {
代码语言:javascript复制
      "field": "pagerank"
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

而当特征(指属性)集合是稀疏时,适合使用 rank features 类型

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "topics": {
代码语言:javascript复制
        "type": "rank_features" 
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{
代码语言:javascript复制
  "topics": { 
代码语言:javascript复制
    "politics": 20,
代码语言:javascript复制
    "economics": 50.8
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/2{
代码语言:javascript复制
  "topics": {
代码语言:javascript复制
    "politics": 5.2,
代码语言:javascript复制
    "sports": 80.1
代码语言:javascript复制
  }}
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "rank_feature": {
代码语言:javascript复制
      "field": "topics.politics"
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

v Geo point 空间坐标类型

坐标字段类型可以用于以下情况:

1. 根据距离对文档进行排序

2. 将距离加入到文档的相关性得分计算中

3. 聚合 距离 范围内的文档

4. 可以通过 边界(bounding) 范围(distance of central point) 多边形

代码语言:javascript复制
PUT my-index-000001{
代码语言:javascript复制
  "mappings": {
代码语言:javascript复制
    "properties": {
代码语言:javascript复制
      "location": {
代码语言:javascript复制
        "type": "geo_point"
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/1{
代码语言:javascript复制
  "text": "Geo-point as an object",
代码语言:javascript复制
  "location": { 
代码语言:javascript复制
    "lat": 41.12,
代码语言:javascript复制
    "lon": -71.34
代码语言:javascript复制
  }}
代码语言:javascript复制
PUT my-index-000001/_doc/2{
代码语言:javascript复制
  "text": "Geo-point as a string",
代码语言:javascript复制
  "location": "41.12,-71.34" }
代码语言:javascript复制
PUT my-index-000001/_doc/3{
代码语言:javascript复制
  "text": "Geo-point as a geohash",
代码语言:javascript复制
  "location": "drm3btev3e86" }
代码语言:javascript复制
PUT my-index-000001/_doc/4{
代码语言:javascript复制
  "text": "Geo-point as an array",
代码语言:javascript复制
  "location": [ -71.34, 41.12 ] }
代码语言:javascript复制
PUT my-index-000001/_doc/5{
代码语言:javascript复制
  "text": "Geo-point as a WKT POINT primitive",
代码语言:javascript复制
  "location" : "POINT (-71.34 41.12)" }
代码语言:javascript复制
GET my-index-000001/_search{
代码语言:javascript复制
  "query": {
代码语言:javascript复制
    "geo_bounding_box": { 
代码语言:javascript复制
      "location": {
代码语言:javascript复制
        "top_left": {
代码语言:javascript复制
          "lat": 42,
代码语言:javascript复制
          "lon": -72
代码语言:javascript复制
        },
代码语言:javascript复制
        "bottom_right": {
代码语言:javascript复制
          "lat": 40,
代码语言:javascript复制
          "lon": -74
代码语言:javascript复制
        }
代码语言:javascript复制
      }
代码语言:javascript复制
    }
代码语言:javascript复制
  }}

ignore_malformed

设置为true,错误的坐标将被忽略,默认为true,对于错误的坐标,将会抛出异常

ignore_z_value

默认为true,3维数据可以被索引,但只有 经度和维度被索引,第3维坐标被忽略,如果设置为false ,则会抛出异常

null_value

接受坐标为null的情况,以缺失对待

1. Document Api

写操作过程

  1. Validate incoming operation and reject it if structurally invalid (Example: have an object field where a number is expected)

验证写操作(增加,更新,删除)是否合法

  1. Execute the operation locally i.e. indexing or deleting the relevant document. This will also validate the content of fields and reject if needed

在主分片上执行写操作

  1. Forward the operation to each replica in the current in-sync copies set. If there are multiple replicas, this is done in parallel.

并行将写操作,复制到 复制分片replica

  1. Once all replicas have successfully performed the operation and responded to the primary, the primary acknowledges the successful completion of the request to the client.

主分片等待所有的replica 都执行成功,再将结果返回给客户端

如果主分片失败,持有该分片的node 会向master node发送消息,索引操作就会等待直到 从replica中选出主分片,默认等待1分钟;索引操作就会被重定向到新的primary 分片上进行处理;同时,master node 会监控所有node,如果出现一些异常情况(比如出现网络分区),就会降级primary。

在primary执行索引操作成功后,会将操作发送给replica执行,如果其中的replica 执行失败或replica未收到索引操作请求,一旦在replica 上执行失败后,primary 就会向master发送移除replica的请求,如果移除成功,primary在收到其他replica执行结果后,响应客户端,master会重新重构新的分片到其他的node上,已使索引达到健康的状态。

Primary 分片也会通过replica 来验证自己是否还是主分片,一般出现在网络分区中或者长时间的GC;在被降级前,primary会继续处理到来的请求,当replica 收到来之伪主分片的请求时,会拒绝,并告诉primary 你已不是主分片了,此时primary降级,然后连接到新的主分片

读过程:

  1. Resolve the read requests to the relevant shards. Note that since most searches will be sent to one or more indices, they typically need to read from multiple shards, each representing a different subset of the data.

决定读请求应该访问哪个分片,大多数读请求都会访问一个或多个索引,

  1. Select an active copy of each relevant shard, from the shard replication group. This can be either the primary or a replica. By default, Elasticsearch will simply round robin between the shard copies.

选择一个分片执行读请求,分片即可以是主分片也可以是复制分片,默认情况下回采取轮询的方式

  1. Send shard level read requests to the selected copies.

向所选择的分片发送请求

  1. Combine the results and respond. Note that in the case of get by ID look up, only one shard is relevant and this step can be skipped.

组合查询的结果;如果是 通过id进行查询的话,是可以直接定位在一个分片上,执行查询的。

如果在shard 中执行失败,协调器node 会选择其他的副本继续执行查询,直到没有可用的副本

索引API

https://www.elastic.co/guide/en/elasticsearch/reference/7.0/docs-index_.html

0 人点赞