前言
在互联网中,我们查询的信息主要包括文章、视频、图片、网站信息等等
根据数据的格式,我们会将数据分为三大类:
结构化数据,通常表现为二维的表结构,例如MySQL、Oracle 中的表结构数据
 
非结构化数据,无法用二维表表示的数据,例如服务器日志、通讯记录、工作文档、报表等,这些数据维度管,数据量大,数据的存储、查询成本大,往往需要专业的人员和统计模型进行处理,通常会将这些数据保存到 NoSQL 数据库中去,例如 Redis 、 MongoDB,通常是以 key - value 键值对
- 优点:查询快
 
- 缺点:由于他们的非特征性和歧义性,会更难理解
 
 
半结构化数据,将数据结构和内容混在一起,没有明显的区分,例如存储员工的简历,通常装载在XML、Html等中 ,保存在 MongoDB、Redis 、HBase 中
 
如何快速、准确地查询结构化数据、非结构化数据当中的内容,ElasticSearch 就是为此诞生的
一、索引
索引创建之后是不允许被修改的,只能被删除
查询
 | ## 查看 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"] }
 
  |