目录
1、多条件查询-假设想找出小米牌子,价格为3999元的。(must相当于数据库的&&)
2、多条件查询-假设想找出小米和华为的牌子。(should相当于数据库的||)
6、通配查询 wildcard查询 相当于mysql中like
3.3、各个年龄的人数分布 (注意,在 ES 的关键词中 aggs 和 aggregations 等价。)
一、主键查询 & 全查询
1、主键查询
GET /shopping/_doc/1
2、全查询
GET /shopping/_search
二、条件查询 & 分页查询 & 查询排序
1、条件查询
1、url带参查询,查找category(类别)为小米的文档
GET /shopping/_search?q=category:小米
请求体带参查询
GET /shopping/_search
{
"query":{
"match":{
"category":"小米"
}
}
}
查找所有文档内容
GET /shopping/_search
{
"query":{
"match_all":{}
}
}
查询指定字段
GET /shopping/_search
{
"query":{
"match_all":{}
},
"_source":["title"]
}
2、分页查询.
2.1、分页查询
注:from= (pageNo-1)*pageSize from指偏移量
size = pageSize
GET /shopping/_search
{
"query":{
"match_all":{}
},
"from":0,
"size":2
}
2.2、分页查询并排序
GET student/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_id": {"order" : "asc"}
}
],
"from": 0,
"size": 6
}
3、查询排序
3.1、查询排序
#先创建索引
PUT student
{
"mappings" : {
"properties" : {
"name" : {
"type" : "keyword"
},
"age" : {
"type" : "integer"
}
}
}
}
#再创建文档
POST _bulk
{ "index" : { "_index" : "student", "_id" : "1" } }
{ "name" : "张三", "age": 12}
{ "index" : { "_index" : "student", "_id" : "2" } }
{ "name" : "李四", "age": 10 }
{ "index" : { "_index" : "student", "_id" : "3" } }
{ "name" : "王五", "age": 11 }
{ "index" : { "_index" : "student", "_id" : "4" } }
{ "name" : "陈六", "age": 11 }
GET student/_search
{
"query": {
"match_all": {}
}
,
"sort": [
{
"age": { "order": "desc"}
}
]
}
3.2、一个字段降序,一个字段升序
//age降序,_id升序:
GET student/_search
{
"query": {
"match_all": {}
}
,
"sort": [
{
"age": { "order": "desc"}
},
{
"_id": {"order" : "asc"}
}
]
}
//_id升序、age降序:
GET student/_search
{
"query": {
"match_all": {}
}
,
"sort": [
{
"_id": {"order" : "asc"}
},
{
"age": { "order": "desc"}
}
]
}
3.3、多字段值排序(字段值不是字段)
如果某个字段是数组,也是可以排序的,不过需要指定 mode 。mode 支持 min、max、avg、sum。
//建立索引
PUT student2
{
"mappings" : {
"properties" : {
"name" : {
"type" : "keyword"
},
"score" : {
"type" : "integer"
}
}
}
}
# 添加文档
POST _bulk
{ "index" : { "_index" : "student2", "_id" : "1" } }
{ "name" : "张三", "score": [80, 90]}
{ "index" : { "_index" : "student2", "_id" : "2" } }
{ "name" : "李四", "score": [78, 95] }
# 按照 score 的最小值排序
GET student2/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"score": {"order" : "asc", "mode": "min"}
}
]
}
三、多条件查询 & 范围查询
1、多条件查询-假设想找出小米牌子,价格为3999元的。(must相当于数据库的&&)
GET /shopping/_search
{
"query":{
"bool":{
"must":[{
"match":{
"category":"小米"
}
},{
"match":{
"price":3999.00
}
}]
}
}
}
2、多条件查询-假设想找出小米和华为的牌子。(should相当于数据库的||)
GET /shopping/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"category": "小米"
}
},
{
"match": {
"category": "华为"
}
}
],
"filter": {
"range": {
"price": {
"gt": 2000
}
}
}
}
}
}
3、范围查询
假设想找出小米和华为的牌子,价格大于2000元的手机。
* gt: >
* gte: >=
* lt: <
* lte: <=
POST /user/_search
{
"query": {
"range": {
"age": {
"gt": 30,
"lte": 50
}
}
}
}
GET /shopping/_search
{
"query":{
"bool":{
"should":[{
"match":{
"category":"小米"
}
},{
"match":{
"category":"华为"
}
}],
"filter":{
"range":{
"price":{
"gt":2000
}
}
}
}
}
}
4、模糊查询 fuzzy
返回包含与搜索字词相似的字词的文档。
编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:
更改字符(box → fox)
删除字符(black → lack)
插入字符(sic → sick)
转置两个相邻字符(act → cat)
为了找到相似的术语,fuzzy 查询会在指定的编辑距离内创建一组搜索词的所有可能的变体
通过 fuzziness 修改编辑距离。一般使用默认值 AUTO,根据术语的长度生成编辑距离。
prefix_length 指定前面几个字符不允许出错
POST /user/_search
{
"query": {
"fuzzy": {
"name": {
"value": "wangwu",
}
}
}
}
POST /user/_search
{
"query": {
"fuzzy": {
"name": {
"value": "wangwu",
"fuzziness": 2
}
}
}
}
POST /user/_search
{
"query": {
"fuzzy": {
"name": {
"value": "wangwu",
"fuzziness": 2,
"prefix_length": 1
}
}
}
}
5、前缀查询 prefifix
通过一个关键字去指定一个field的前缀
POST /user/_search
{
"query": {
"prefix": {
"corpName": {
"value": "wang"
}
}
}
}
6、通配查询 wildcard查询 相当于mysql中like
和mysql中的like一个套路,可以在查询时,在字符串中指定通配符 * 和 占位符 ?
POST /user/_search
{
"query": {
"wildcard": {
"name": {
"value": "wang*" #可以使用*和?指定通配符和占位符
}
}
}
}
7、正则查询
可以通过编写的正则表达式去匹配内容
PUT user2/_bulk
{"index":{}}
{"name":"张三","mobile":"17775427990"}
{"index":{}}
{"name":"李四","mobile":"18095278888"}
POST /user2/_search
{
"query": {
"regexp": {
"mobile": "180[0-9]{8}"
}
} }
8、filter查询
query是根据你的查询条件,去计算文档的匹配度得到一个分数,并且根据扥书进行排序,不会缓存数据。
filter是根据你的查询条件去查询文档,不去计算分数,而且filter会对经常被过滤的数据进行缓存
POST /user/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"name": "zhangsan"
}
},
{
"range": {
"age": {
"lte": 30
}
}
}
]
}
}
}
9、条件查询 term和terms
term的查询是代表完全匹配,搜索之前不会对你搜索的关键字进行分词,对你的关键字去文档分词库中去匹配内容
terms和term的查询机制是一样,都不会将指定的查询关键字进行分词,直接去分词库 中匹配,找到相应文档内容。
terms是在针对一个字段包含多个值的时候使用。
term:where age = 30;
terms:where age =30 or age =? or age = ?
#term
POST /user/_search
{
"from": 0,
"size": 5,
"query": {
"term": {
"age": {
"value": "30"
}
}
}
}
#terms
POST /user/_search
{
"from": 0,
"size": 5,
"query": {
"terms": {
"age": [
"20",
"30"
]
}
}
}
10、match查询
match查询属于高层查询,他会根据你查询的字段类型不一样,采用不同的查询方式."
详见下文全文检索示例
四、全文检索 & 完全匹配 & 高亮查询
1、全文检索
这功能像搜索引擎那样,如品牌输入“小华”,返回结果带回品牌有“小米”和华为的。
GET /shopping/_search
{
"query":{
"match":{
"category" : "小华"
}
}
}
2、全文匹配
GET /shopping/_search
{
"query":{
"match_phrase":{
"category" : "为"
}
}
}
3、高亮查询
下面是把查询出的 “为” 字高亮
GET /shopping/_search
{
"query":{
"match_phrase":{
"category" : "为"
}
},
"highlight":{
"fields":{
"category":{}
}
}
}
4、查询结果只展示部分字段
如下,查询结果只展示name字段, includes 换成 include 也可以,但会提示 include 已经废弃。所以不建议使用 include
GET student/_search
{
"query": {
"match": {
"age": "12"
}
},
"_source": {
"includes": [
"name"
]
}
}
五、聚合查询
ES聚合分析查询的写法如下
"aggregations" : {
"<aggregation_name>" : { <!--聚合的名字 -->
"<aggregation_type>" : { <!--聚合的类型 -->
<aggregation_body> <!--聚合体:对哪些字段进行聚合 -->
}
[,"meta" : { [<meta_data_body>] } ]? <!--元 -->
[,"aggregations" : { [<sub_aggregation>]+ } ]? <!--在聚合里面在定义子聚合 -->
}
}
聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很多其他的聚合,例如取最大值max、平均值avg等等。
1、接下来按price字段进行分组
GET /shopping/_search
{
"aggs":{//聚合操作
"price_group":{//名称,随意起名
"terms":{//分组
"field":"price"//分组字段
}
}
}
}
上面返回结果会附带原始数据的。若不想要附带原始数据的结果,如下:
GET /shopping/_search
{
"aggs":{
"price_group":{
"terms":{
"field":"price"
}
}
},
"size":0
}
2、若想对所有手机价格求平均值。
GET /shopping/_search
{
"aggs":{
"price_avg":{//名称,随意起名
"avg":{//求平均
"field":"price"
}
}
},
"size":0
}
3、聚合查询示例
3.1、先创建索引和导入数据
PUT student8
{
"mappings" : {
"properties" : {
"name" : {
"type" : "keyword"
},
"age" : {
"type" : "integer"
},
"height": {
"type": "integer"
}
}
}
}
#一共4条数据,其中张三没有身高 height 的数据
POST _bulk
{ "index" : { "_index" : "student8", "_id" : "1" } }
{ "name" : "张三", "age": 12 }
{ "index" : { "_index" : "student8", "_id" : "2" } }
{ "name" : "李四", "age": 10, "height": 112 }
{ "index" : { "_index" : "student8", "_id" : "3" } }
{ "name" : "王五", "age": 11, "height": 108 }
{ "index" : { "_index" : "student8", "_id" : "4" } }
{ "name" : "陈六", "age": 11, "height": 111 }
#查询所有数据
GET student8/_search
#总人数
POST student8/_count
3.2、11 岁的学生总人数
#方法1:
POST student8/_count
{
"query": {
"bool": {
"must": [
{
"term": {"age": 11}
}
]
}
}
}
#方法2:查询后进行聚合:
GET student8/_search
{
"query": {
"bool": {
"must": [
{"term": {"age": 11} }
]
}
},
"aggs":{
"age_count": {
"terms": {"field": "age"}
}
},
"size": 0
}
3.3、各个年龄的人数分布 (注意,在 ES 的关键词中 aggs 和 aggregations 等价。)
方法1:
POST student8/_search
{
"aggs":{
"age_count": {
"terms": {"field": "age"}
}
},
"size": 0
}
方法2:
POST student8/_search
{
"size": 0,
"aggregations": {
"group_by_age": {
"aggregations": {
"count_age": {
"value_count": {
"field": "_index"
}
}
},
"terms": {
"field": "age"
}
}
}
}
3.4、各个身高的人数分布
POST student8/_search
{
"aggs":{
"group_by_height": {
"terms": {"field": "height"}
}
},
"size": 0
}
无身高数据的张三 未被统计。
3.5、学生的平均年龄、最小年龄、最大年龄、年龄之和
stats 指令,会计算出指定字段的 count、min、max、avg、sum。
方式1:
POST student8/_search
{
"aggs":{
"age_stat": {
"stats": {"field": "age"}
}
},
"size": 0
}
方式2:
POST student8/_search
{
"aggs":{
"age_avg": {
"avg": {"field": "age"}
},
"age_sum": {
"sum": {"field": "age"}
},
"age_min": {
"min": {"field": "age"}
},
"age_max": {
"max": {"field": "age"}
},
"age_count": {
"value_count": {"field": "age"}
}
},
"size": 0
}
3.6、每个年龄的平均身高是多少
POST student8/_search
{
"size": 0,
"aggregations": {
"group_by_age": {
"aggregations": {
"avg_height": {
"avg": {
"field": "height"
}
}
},
"terms": {
"field": "age"
}
}
}
}
3.7、获取每个年龄的平均身高,并按照年龄从小到大排序
方式1:
#_term已经废弃,使用_key
POST student8/_search
{
"size": 0,
"aggregations": {
"group_by_age": {
"aggregations": {
"avg_height": {
"avg": {
"field": "height"
}
}
},
"terms": {
"field": "age",
"order": {
"_key": "asc"
}
}
}
}
}
#方式2:桶排序
POST student8/_search
{
"size": 0,
"aggregations": {
"group_by_age": {
"aggregations": {
"avg_height": {
"avg": {
"field": "height"
}
},
"bucket_sort_by_avg_height": {
"bucket_sort": {
"sort": [
{"_key": {"order": "asc"}}
]
}
}
},
"terms": {
"field": "age"
}
}
}
}
3.8、获取每个年龄的平均身高,并按照平均身高从大到小排序
#方式1
POST student8/_search
{
"size": 0,
"aggregations": {
"group_by_age": {
"aggregations": {
"avg_height": {
"avg": {
"field": "height"
}
}
},
"terms": {
"field": "age",
"order": {
"_key": "asc"
}
}
}
}
}
#方式2
POST student8/_search
{
"size": 0,
"aggregations": {
"group_by_age": {
"aggregations": {
"avg_height": {
"avg": {
"field": "height"
}
},
"bucket_sort_by_avg_height": {
"bucket_sort": {
"sort": [
{"avg_height": {"order": "desc"}}
]
}
}
},
"terms": {
"field": "age"
}
}
}
}
4、各种聚合查询-示例
ES聚合指标:value_count: 计数
cardinality: 去重计数
avg: 平均值
sum: 求和
max: 最大值
min: 最小值
status:多种聚合结果,总记录数,最大值,最小值,平均值,汇总值
top_hits: 简单来说就是聚合分组后从每一个组取部分数据作为结果返回
percentiles: 百分比
percentile ranks:文档值占比
#求和(Sum)
GET teacher_info/_search
{
"size":0,
"aggs":{
"sum_salary":{
"sum":{
"field":"salary"
}
}
}
}
#最大值(Max)
GET /teacher_info/_search
{
"size":0,
"aggs":{
"max_salary":{
"max":{
"field":"salary"
}
}
}
#最小值(Min
GET /teacher_info/_search
{
"size":"0",
"aggs":{
"min_salary":{
"min":{
"field":"salary"
}
}
}
}
#平均值(Avg
GET /teacher_info/_search
{
"size":"0",
"aggs":{
"avg_salary":{
"avg":{
"field":"salary"
}
}
}
}
#去重数值(cardinality)类似mysql的count distinct
案例:老师一共教了多少学科
GET /teacher_info/_search
{
"size":0,
"aggs":{
"job_count":{
"cardinality": {
"field": "job"
}
}
}
}
#多值查询-最大最小值和平均值
GET /teacher_info/_search
{
"size":0,
"aggs":{
"max_salary":{
"max":{
"field":"salary"
}
},
"min_salary":{
"min":{
"field":"salary"
}
},
"avg_salary":{
"avg":{
"field":"salary"
}
}
}
}
#返回多个聚合值(Status)
stats统计,请求后会直接显示多种聚合结果,总记录数,最大值,最小值,平均值,汇总值
GET /teacher_info/_search
{
"size":0,
"aggs":{
"salary_stats":{
"stats":{
"field":"salary"
}
}
}
}
#根据性别分组,展示工资排名top3(展示的是男top3和女top3)
POST _bulk
{ "index" : { "_index" : "teacher_info", "_id" : "1" } }
{ "name" : "张三","job" : "语文", "age": 24, "salary": 50 ,"sex":"男"}
{ "index" : { "_index" : "teacher_info", "_id" : "2" } }
{ "name" : "李四", "job" : "数学", "age": 25, "salary": 80 ,"sex":"男"}
{ "index" : { "_index" : "teacher_info", "_id" : "3" } }
{ "name" : "王五","job" : "英语", "age": 26, "salary": 90 ,"sex":"女"}
{ "index" : { "_index" : "teacher_info", "_id" : "4" } }
{ "name" : "陈六", "job" : "语文", "age": 25, "salary": 100 ,"sex":"男"}
GET /teacher_info/_search?size=0
{
"aggs":{
"top_tags":{
"terms":{
"field":"sex.keyword"
},
"aggs":{
"top_sales_hits":{
"top_hits":{
"sort":[
{
"salary":{
"order":"desc"
}
}
],
"_source":{
"includes":["name","sex","salary"]
},
"size":3
}
}
}
}
}
}
六、滚动查询 scroll
注意:滚动查询不适合做实时查询,一般用于定数任务进行数据采集整理
1、数据准备
PUT student7
{
"mappings" : {
"properties" : {
"name" : {
"type" : "keyword"
},
"age" : {
"type" : "integer"
}
}
}
}
POST _bulk
{ "index" : { "_index" : "student7", "_id" : "1" } }
{ "name" : "张三", "age": 12}
{ "index" : { "_index" : "student7", "_id" : "2" } }
{ "name" : "李四", "age": 10 }
{ "index" : { "_index" : "student7", "_id" : "3" } }
{ "name" : "王五", "age": 11 }
{ "index" : { "_index" : "student7", "_id" : "4" } }
{ "name" : "陈六", "age": 11 }
2、查询示例1
GET student7/_search?scroll=1m
{
"query": {
"match_all": {}
},
"sort": {
"name": "desc"
},
"size": 10
}
返回结果中有 _scroll_id ,我们下次查询基于 scroll_id 查询:
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFl9UZnFZQnBBU3ZlWW01SzUyS2huZXcAAAAAAABz9xZiS0YtSXdMMFJQbUZSa3o3cG5tYXBR"
}
如果查不到数据了,返回值中的 scroll_id 和查询是的 scroll_id 是一个值。继续查询时,返回值和上面的相同。--可根据scroll进行判断防止递归
因为指定保存 scroll 上下文的时间是 1分钟( 1m ),所以,过1分钟后查询,会报错。
3、查询示例2:
GET student7/_search?scroll=1m
{
"query": {
"match_all": {}
},
"sort": {
"name": "desc"
},
"size": 3
}
POST /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFl9UZnFZQnBBU3ZlWW01SzUyS2huZXcAAAAAAAB0QxZiS0YtSXdMMFJQbUZSa3o3cG5tYXBR"
}
4、什么时候结束查询?
当查询结果数量小于第一次查询执行的 size时,结束查询。
5、删除
删除scroll在ES上下文中的数据
DELETE /_search/scroll/scroll_id