前言
在互联网中,我们查询的信息主要包括文章、视频、图片、网站信息等等
根据数据的格式,我们会将数据分为三大类:
- 结构化数据,通常表现为二维的表结构,例如MySQL、Oracle 中的表结构数据
- 非结构化数据,无法用二维表表示的数据,例如服务器日志、通讯记录、工作文档、报表等,这些数据维度管,数据量大,数据的存储、查询成本大,往往需要专业的人员和统计模型进行处理,通常会将这些数据保存到 NoSQL 数据库中去,例如 Redis 、 MongoDB,通常是以 key - value 键值对
- 优点:查询快
- 缺点:由于他们的非特征性和歧义性,会更难理解
- 半结构化数据,将数据结构和内容混在一起,没有明显的区分,例如存储员工的简历,通常装载在XML、Html等中 ,保存在 MongoDB、Redis 、HBase 中
- 优点:能够灵活的扩展
- 缺点:查询内容不易
如何快速、准确地查询结构化数据、非结构化数据当中的内容,ElasticSearch 就是为此诞生的
一、索引
索引创建之后是不允许被修改的,只能被删除
查询
1 2 3 4 5
| ## 查看 es 中的所有索引 GET /_cat/indices
## 查看 es 中的所有索引,包含标题 GET /_cat/indices?v
|
创建
1 2 3 4 5 6 7 8 9 10 11
| ## 创建索引 PUT /索引名
## 创建索引,并设置属性 PUT /索引名 { "settings": { "number_of_shards": 1, ## 指定主分片的数量 "number_of_replicas": 0 ## 指定副本分片的数量 } }
|
删除
二、映射
- 字符串类型:keyword、text
- 数字类型:integer、long
- 小数类型:float、double
- 布尔类型:boolean
- 日期类型:date
创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| ## 创建商品索引 products 指定 mapping { id, title, price, created_at, description } PUT /products { "settings": { "number_of_shards": 1, ## 指定主分片的数量 "number_of_replicas": 0 ## 指定副本分片的数量 }, "mappings": { "properties": { "id": { "type": "integer" }, "title": { "type": "keyword" }, "price": { "type": "double" }, "created_at": { "type": "date" }, "description": { "type": "text" } } } }
|
查看
三、文档
创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| POST /索引名/_doc/id ## 指定文档 id 如:
POST /products/_doc/1 { "title": "iphone13", "price": 8999.9, "created_at": "2021-09-15", "description": "xxxxxxx" }
POST /索引名/_doc ## 不指定文档 id,那么内部将会自动分配一个 uuid 如:
POST /products/_doc/1 { "title": "iphone13", "price": 8999.9, "created_at": "2021-09-15", "description": "xxxxxxx" }
|
查询
删除
更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| # 第一种方式 PUT /索引名/_doc/id 如: PUT /products/doc/1 ## 先删除,再插入。可能会导致原来存有的映射丢失 { "title": "iphone14" }
# 第二种方式 POST /索引名/_doc/id/_update { "doc": { } } 如: POST /products/_doc/1/_update { "doc": { "title": "iphone14" } }
|
五、批量操作 _bulk
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 文档批量操作 _bulk POST /索引名/_doc/_bulk 如: POST /products/_doc/_bulk # 特别注意: # 一、批操作不能回车换行 # 二、不是一个原子性操作,不会因为某一条有误而导致整个批操作失败
# 以下是关于 添加 更新 删除 的批操作 {"index": {"_id": 2}} {"id": 2,"title": "日本豆","price": 1.8,"created_at": "2012-11-12","description": "好难吃的日本豆!"} {"update":{"_id": 3}} {"doc":{"title":"小于豆腐"}} {"delete":{"_id":2}}
|
六、Query Domain Specified Language(DSL)
Query DSL
是利用 Rest API
传递 JSON
格式的请求体数据与 ES 进行交互
这种方式的查询语法让 ES 检索变得更加强大,更加简洁
语法:
1 2 3
| Get /索引名/_doc/_search {Json格式请求体数据} 或 Get /索引名/_search {Json格式请求体数据}
|
查询所有 [match_all]
1 2 3 4 5 6
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { "match_all": {} } }
|
关键词查询 [term]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| # 注意:term 基于关键词查询 # 一、查询 keyword 类型时,不会进行分词,所以要使用全部内容进行搜索 # 二、查询 text 类型时,默认 es 标准分词器对中文单字分词,对英文单词分词 # 三、查询 integer、double、double、date 类型时,不会进行分词 Get /索引名/_doc/_search | Get /索引名/_search { "query": { "term": { "映射名": { "value": xxxx } } } } 如: GET /products/_search { "query": { "term": { "price": { "value": 49999 } } } }
|
总结
- 在 ES 中除了 text 类型会进行分词,其余类型均不会分词
- 在 ES 中默认使用标准分词器,即对中文是单字分词,英文是单词分词
范围查询 [range]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { "range": { "映射名": {
} } } } 如: GET /products/_search { "query": { "range": { "price": { "gte": 1400, "lte": 9999 } } } }
|
前缀查询 [prefix]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { "prefix": { "映射名": { "value": "xxx" } } } } 如: GET /products/_search { "query": { "prefix": { "title": { "value": "ipho" } } } }
|
通配符查询 [wildcard]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| Get /索引名/_doc/_search | Get /索引名/_search # ? 用来匹配一个任意字符 # * 用来匹配多个任意字符 { "query": { "wildcard": { "映射名": { "value": "x*?" } } } } 如: GET /products/_search { "query": { "wildcard": { "description": { "value": "inp*" } } } }
|
多id查询 [ids]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { "ids": { "values": [ "id1", "id2" ] } } } 如: GET /products/_search { "query": { "ids": { "values": ["xxxxxx", "xxxxxxxxxx"] } } }
|
模糊查询 [fuzzy]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| # 注意:最大模糊错误在 0 - 2 之间 Get /索引名/_doc/_search | Get /索引名/_search { "query": { "fuzzy": { "映射名": "xxxx" } } } 如: GET /products/_search { "query": { "fuzzy": { "description": "iphoneoooes" } } }
|
总结
- 搜索关键词长度小于等于 2 不允许存在模糊
- 搜索关键词长度 3 - 5 允许存在一次模糊
- 搜索关键词长度大于等于 5 允许存在两次模糊
布尔查询 [bool]
用来组合多个条件实现复杂查询
must:相当于 && 同时成立
should:相当于 || 成立一个就行
must_not:相当于 ! 不能满足一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { "bool": { "should | must | must_not": { } } } } 如: # 查询满足 id 为 1 或 title 含有豆腐的值 GET /products/_search { "query": { "bool": { "should": [ { "ids": { "values": [1] } }, { "term": { "title": { "values": "豆腐" } } } ] } } }
|
多字段查询 [multi_match]
1 2 3 4 5 6 7 8 9 10 11 12
| # query 根据字段类型选择是否分词: # 如果 fields 中含有不分词,将查询条件作为整体进行查询 # 如果 fields 中含有分词,将查询条件分词之后进行查询 Get /索引名/_doc/_search | Get /索引名/_search { "query": { "multi_match": { "query": "xxxxx", "fields": ["映射名1", "映射名2"] } } }
|
默认字段分词查询 [query_string]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| # query 根据字段类型选择是否分词: # 如果 fields 中含有不分词,将查询条件作为整体进行查询 # 如果 fields 中含有分词,将查询条件分词之后进行查询 Get /索引名/_doc/_search | Get /索引名/_search { "query": { "query_string": { "default_field": "映射名" "query": "xxxxxx" } } } 如: GET /products/_search { "query": { "query_string": { "default_field": "description", "query": "屏幕真的很不错" } } }
|
返回指定条数 [size]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { ... }, "size": n } 如: GET /products/_search { "query": { "match_all": {} }, "size": 5 }
|
分页查询 [from]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { ... }, "from": 从第几页开始查询 "size": 每页大小 } 如: GET /products/_search { "query": { "match_all": {} }, "from": 0 "size": 5 }
|
指定字段排序 [sort]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { ... }, "sort": [ { "映射名": { "order": "desc" ## 默认是降序 } } ] } 如: GET /products/_search { "query": { "match_all": {} }, "sort": [ { "price": { "order": "desc" } } ] }
|
放回指定字段 [_source]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Get /索引名/_doc/_search | Get /索引名/_search { "query": { ... }, "_source": ["映射名1", "映射名2", "映射名3"] } 如: GET /products/_search { "query": { ... }, "_source": ["id", "title", "description"] }
|