目录
一、索引创建
二、查看索引
1、查看所有索引
2、查看单个索引
三、删除索引
四、映射关系
1、先创建一个索引
2、创建映射
2.1、创建映射
2.2、创建映射设置分片,不设置会默认一个主分片一个备份分片
2.3、ignore_above限定字符长度
2.4、doc_values 属性
2.5、fielddata属性
3、settings中定义索引库的各种属性
3.1、refresh_interval
3.2、max_result_window
3.3、动态映射
五、增加数据
六、简单查询
6.1、查找name含有”小“数据
6.2、查找sex含有”男“数据:
6.3、查询电话
一、索引创建
PUT /shopping
二、查看索引
1、查看所有索引
GET /_cat/indices?v
返回结果: health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .geoip_databases 0CG2YlaPRoWzyYDoI_qrnw 1 0 40 41 37.9mb 37.9mb green open .kibana_task_manager_7.16.2_001 8gMpU8TgSquEjIogLYDx1Q 1 0 18 1009 379.5kb 379.5kb green open .apm-custom-link tdDMOb-6Q72Q0teB9gNOTQ 1 0 0 0 226b 226b green open .kibana_task_manager_1 GJZl69z0SKuI9RYywKzvdA 1 0 2 1 55.2kb 55.2kb green open .kibana_7.16.2_001 -XLPL15WSiCe58OIVby1UA 1 0 31 42 4.7mb 4.7mb green open .apm-agent-configuration A1f3pYIEQiOp2aNuIUWltA 1 0 0 0 226b 226b green open .kibana_1 InKzLmjZQlK_po5a_8VkLQ 1 0 2 0 10.1kb 10.1kb yellow open event_detail_2022 zBGxQH8qS7qoExmZEXL3fw 1 1 29 0 9.9kb 9.9kb yellow open shopping Djjkp-sNQPedDpKZ6cSZRg 1 1 0 0 226b 226b green open .tasks 3DxEBvwzTBSul8tzqh8BmQ 1 0 4 0 27.4kb 27.4kb
表头 含义 health 当前服务器健康状态: green(集群完整) yellow(单点正常、集群不完整) red(单点不正常) status 索引打开、关闭状态 index 索引名 uuid 索引统一编号 pri 主分片数量 rep 副本数量 docs.count 可用文档数量 docs.deleted 文档删除状态(逻辑删除) store.size 主分片和副分片整体占空间大小 pri.store.size 主分片占空间大小
2、查看单个索引
GET /shopping
三、删除索引
DELETE /shopping
四、映射关系
有了索引库,等于有了数据库中的 database。
接下来就需要建索引库(index)中的映射了,类似于数据库(database)中的表结构(table)。
创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。
1、先创建一个索引
PUT /user
2、创建映射
2.1、创建映射
PUT /user/_mapping { "properties": { "name":{ "type": "text", "index": true }, "sex":{ "type": "keyword", "index": true }, "tel":{ "type": "keyword", "index": false } } }
2.2、创建映射设置分片,不设置会默认一个主分片一个备份分片
- number_of_shards:分片的数量;(主分片)
- number_of_replicas:副本的数量;(备份分片)
- 一般配置,副本数少可以提高性能
在mappings中,我们设置索引的字段, 在这里,我们只设置了id和name,id的映射类型是long,name的映射类型是text。 settings:就是索引库设置,其中可以定义索引库的各种属性, 目前我们可以不设置,都走默认 PUT /stu { "settings":{ "number_of_shards":5, "number_of_replicas":1 }, "mappings":{ "properties":{ "id":{ "type":"long" }, "name":{ "type":"text" } } } }
2.3、ignore_above限定字符长度
1、创建 mapping 时,可以为字符串(专指 keyword) 指定 ignore_above ,用来限定字符长度。超过 ignore_above 的字符会被存储,但不会被索引。
注意,是字符长度,一个英文字母是一个字符,一个汉字也是一个字符。
在动态生成的 mapping 中,keyword类型会被设置ignore_above: 256。
ignore_above 可以在创建 mapping 时指定。
PUT my_index { "mappings" : { "properties" : { "note" : { "type" : "keyword", "ignore_above": 4 } } } }
2、ignore_above扩展
POST _bulk {"index":{"_index":"my_index","_id":"1"}} {"note":"一二三"} {"index":{"_index":"my_index","_id":"2"}} {"note":"一二三四"} {"index":{"_index":"my_index","_id":"3"}} {"note":"一二三四五"} #用下面的查询验证 ignore_above # 能查到数据 GET my_index/_search { "query": { "match": { "note": "一二三四" } } } # 不能查到数据 ignore_above限定长度为4,超过的不会被索引 GET my_index/_search { "query": { "match": { "note": "一二三四五" } } }
3、修改 ignore_above 改大改小都行,但只对新数据有效
PUT my_index/_mappings { "properties" : { "note" : { "type" : "keyword", "ignore_above": 2 } } }
2.4、doc_values 属性
字段的 doc_values 属性有两个值, true、false。默认为 true ,即开启。
当 doc_values 为 fasle 时,无法基于该字段排序、聚合、在脚本中访问字段值。
当 doc_values 为 true 时,ES 会增加一个相应的正排索引,这增加的磁盘占用,也会导致索引数据速度慢一些。
#新建索引 PUT student6 { "mappings" : { "properties" : { "name" : { "type" : "keyword", "doc_values": false }, "age" : { "type" : "integer", "doc_values": false } } } } #插入数据 POST _bulk { "index" : { "_index" : "student6", "_id" : "1" } } { "name" : "张三", "age": 12 } { "index" : { "_index" : "student6", "_id" : "2" } } { "name" : "李四", "age": 10 } { "index" : { "_index" : "student6", "_id" : "3" } } { "name" : "王五", "age": 11 } #查询数据并按照age排序,会报错 POST student6/_search { "query": { "match_all": {} }, "sort" : [ {"age": {"order": "desc"}} ], "from": 0, "size": 1 } #获取 age 平均值,会报错 POST student6/_search { "aggs":{ "age_stat": { "avg": {"field": "age"} } }, "from": 0 }
2.5、fielddata属性
在ES中,text类型的字段使用一种叫做fielddata的查询时内存数据结构。当字段被排序,聚合或者通过脚本访问时这种数据结构会被创建。它是通过从磁盘读取每个段的整个反向索引来构建的,然后存存储在java的堆内存中。
fileddata默认是不开启的。Fielddata可能会消耗大量的堆空间,尤其是在加载高基数文本字段时。一旦fielddata已加载到堆中,它将在该段的生命周期内保留。此外,加载fielddata是一个昂贵的过程,可能会导致用户遇到延迟命中。这就是默认情况下禁用fielddata的原因。
PUT shopping3 POST _bulk { "index" : { "_index" : "shopping3", "_id" : "1" } } { "category" : "大米", "price": 12} { "index" : { "_index" : "shopping3", "_id" : "2" } } { "category" : "黄豆", "price": 10 } { "index" : { "_index" : "shopping3", "_id" : "3" } } { "category" : "大米", "price": 12 } #如果尝试对文本字段进行排序,聚合或脚本访问,会报异常 GET /shopping3/_search { "aggs":{ "price_group":{ "terms":{ "field":"category" } } }}
如果要对分词的field执行聚合操作,必须将fielddata设置为true
#先查看mapping,mapping字段类型与下面命令查出的类型一致才可操作 GET /shopping3 PUT shopping3/_mappings { "properties" : { "category" : { "type" : "text", "fielddata": true } } } GET /shopping3/_search { "aggs":{ "price_group":{ "terms":{ "field":"category" } } }} 此时聚合查询正常
3、settings中定义索引库的各种属性
#先建一个索引 PUT /stu2 { "settings": { "index": { "refresh_interval": "5s", "number_of_shards": "5", "translog": { "sync_interval": "5s", "durability": "async" }, "max_result_window": "65536", "number_of_replicas": "1" } }, "mappings":{ "properties":{ "id":{ "type":"long" }, "name":{ "type":"text" } } } }
3.1、refresh_interval
1、当数据添加到索引后并不能马上被查询到,等到索引刷新后才会被查询到。 refresh_interval 配置的刷新间隔。refresh_interval 的默认值是 1s
单位:ms: 毫秒 s: 秒 m: 分钟 如果是指定的纯数字,单位是毫秒
2、当 refresh_interval 为 -1 时,意味着不刷新索引。
3、当需要大量导入数据到ES中,可以将 refresh_interval 设置为 -1 以加快导入速度。导入结束后,再将 refresh_interval 设置为一个正数,例如1s。或者手动 refresh 索引。
4、将某索引的 refresh_interval 设置为 1分钟
PUT stu2/_settings { "index" : { "refresh_interval" : "1m" } }
5、添加数据时忽略 refresh_interval 配置,直接触发刷新索引(一般用不到)
POST stu2/_doc?refresh { "name": "张三2" }
6、重置 refresh_interval
PUT /stu2/_settings { "index" : { "refresh_interval" : null } }
3.2、max_result_window
es对from + size的大小进行限制,必须小于等于10000
因为es的优势在于搜索,不在于分页,对此做限制(10000)就是为不影响其性能,业务有需求可以按照下面方法设置放大:
PUT /stu2/_settings { "index":{ "max_result_window":100000000 } }
3.3、动态映射
dynamic用来配置处理新出现字段的行为,有true,false,strict 三种。
true 是默认值,会自动在 mapping 中添加字段,并在文档中保存新字段的值。
false 代表不会在 mapping 中添加字段,但会将数据存起来。
strict 代表既不会新增字段,也不会保存新字段的内容,遇到新字段直接报错。 另外,对于嵌套类型的字段,可以单独设置。
默认情况下,我们向索引中写入数据,如果有些字段之前未定义过,ES会自动猜测其类型,然后在mapping中生成。
#新建索引 PUT student3 { "mappings": { "properties": { "name": { "type": "keyword", "doc_values": false } } }, "settings": { "number_of_shards": "8", "number_of_replicas": "2" } } #批量插入 POST _bulk { "index" : { "_index" : "student3", "_id" : "1" } } { "name" : "张三", "age": 12 } #查询 GET student3/_search
查询结果有 age
GET student3/_mapping
age 出现在了 mapping 中,且自动判断为 long 类型。
有时,自动判断的类型可能是不符合我们的预期的,但是呢,类型一旦确定,又是不能更改的。所以我们要谨慎对待这种特性。
dynamic 可以用来配置相关行为,如下配置:
PUT student4 { "mappings": { "dynamic": "false", "properties": { "name": { "type": "keyword", "doc_values": false } } }, "settings": { "number_of_shards": "8", "number_of_replicas": "2" } } PUT student5 { "mappings": { "dynamic": "strict", "properties": { "name": { "type": "keyword", "doc_values": false } } }, "settings": { "number_of_shards": "8", "number_of_replicas": "2" } }
五、增加数据
POST /user/_doc/1001 { "name":"小米", "sex":"男的", "tel":"1111" }
六、简单查询
6.1、查找name含有”小“数据
GET /user/_search { "query":{ "match":{ "name":"小" } } }
6.2、查找sex含有”男“数据:
找不想要的结果,只因创建映射时"sex"的类型为"keyword"。
"sex"只能完全为”男的“,才能得出原数据。
GET /user/_search { "query":{ "match":{ "sex":"男" } } } GET /user/_search { "query":{ "match":{ "sex":"男的" } } }
6.3、查询电话
查询会报错,报错只因创建映射时"tel"的"index"为false。
GET /user/_search { "query":{ "match":{ "tel":"11" } } } 返回结果如下: { "error" : { "root_cause" : [ { "type" : "query_shard_exception", "reason" : "failed to create query: Cannot search on field [tel] since it is not indexed.", "index_uuid" : "angUCPxrQWGPBRb-gMci4Q", "index" : "user" } ], "type" : "search_phase_execution_exception", "reason" : "all shards failed", "phase" : "query", "grouped" : true, "failed_shards" : [ { "shard" : 0, "index" : "user", "node" : "bKF-IwL0RPmFRkz7pnmapQ", "reason" : { "type" : "query_shard_exception", "reason" : "failed to create query: Cannot search on field [tel] since it is not indexed.", "index_uuid" : "angUCPxrQWGPBRb-gMci4Q", "index" : "user", "caused_by" : { "type" : "illegal_argument_exception", "reason" : "Cannot search on field [tel] since it is not indexed." } } } ] }, "status" : 400 }