关键字 | 含义 | 类比SQL |
---|---|---|
query | 查询 | select |
bool | 多个组合条件 | selext xxx from xxx where age=20 and gender=male |
filter | 一个过滤条件 | where |
term | 精确匹配 | = |
match | 全文检索,会分词 | |
must | 在过滤条件中使用,代表必须包含 | |
fuzzy | 模糊匹配 | dick 联想到 nick pick |
from | 从哪一条开始取 | |
size | 取多少条 | limit |
_source | 只选择某些字段 | select 字段 |
match_phrase | 短语匹配,将输入的查询内容整个作为整体进行查询,不切词 | |
multi_match | 一次到多个子弹中匹配内容 | or |
检索
全文检索
select * from stu;
# 协议方法 索引/类型/_search
GET stu/_search
字段全值匹配检索
检索前提:如果是语句,那么会将语句分为词,我们的sql过滤条件就只能是切词,而不能是语句,因为索引只存切开的词,不存整条语句
这里的全值就是字面意思,意思是去匹配整个词i love you
而i love you在索引中是不存在的
GET /test02/_search
{
"query": {
"bool": {
"filter": {
"term": {
"name": "i love you"
}
}
}
}
}
查询结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
没有对应的查询条件,因为ik_max_word分词器会把“i love you”分成以下词组
i 、love、you
我们会发现并没有“i love you”这几个字组合起来的词,因此查不到。
写条件的时候只能写:
GET /test02/_search
{
"query": {
"bool": {
"filter": {
"term": {
"name": "love" (或i或you)
}
}
}
}
}
第二种:match_phrase 搜索
既可以匹配分词又能匹配整个i love you
https://juejin.cn/post/6992593362675040292
字段分词匹配检索
这里分词也是字面意思,将i love you拆开,i匹配上了, love也匹配上了,you也匹配上了,所以比分相对比较高
GET test02/_search
{
"query": {
"match": {
"name": "i love you"
}
}
}
(也会拆词,但是也能匹配整条 i love you)
结果展示:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 2.2169428,
"hits" : [
{
"_index" : "test02",
"_id" : "pAAMiH8BRK4hWm3D8TBD",
"_score" : 2.2169428,
"_source" : {
"id" : "004",
"name" : "i love you"
}
}
]
}
}
两者结合使用
比较特别的地方:must关键字
GET student/_search
{
"query": {
"bool": {
"filter": {
"term": {
"sex": "male"
}
}
, "must": [
{
"match": {
"favo": "海狗人参丸"
}
}
]
}
}
}
字段模糊匹配检索
相当智能
查ffmale,可以模糊匹配出female
GET student/_search
{
"query": {
"fuzzy": {
"sex": "ffmale" 查ffmale,可以模糊匹配出female
}
}
}
[
](https://juejin.cn/post/6992593362675040292)
分页检索
GET student/_search
{
"from": 0, (从第几条开始)
"size": 1 (显示几条)
}
聚合
1.结构
aggregations|aggs
"aggregations" :
{
--aggregation_name:聚合字段名
"<aggregation_name>" :
{
--聚合运算的类型,类比,sum,avg,count(Term),min,max sum()
"<aggregation_type>" :
{
--num 对什么字段进行聚合
<aggregation_body>
}
-- 对哪些表进行聚合,类比tablea,不写,将meta写在url
[,"meta" : { [<meta_data_body>] } ]?
--子聚合,在当前聚合的基础上,继续聚合
[,"aggregations" : { [<sub_aggregation>]+ } ]?
}
--
[,"<aggregation_name_2>" : { ... } ]*
}
count 等价于 term
count(*) ======== sum(if(gender = 'male',1,0))
select
a,max(sum_num) --子聚合
from
(select
a,b,sum(num) sum_num,max(num) max_num
from tablea
where xxx
group by a,b) tmp
group by a
2.聚合报错
“type”: “illegal_argument_exception”, “reason”: “Fielddata is disabled on text fields by default. Set fielddata=true on [gender] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.” TEXT类型,因为涉及到分词,无法被聚合! 解决: 使用KEYWORD类型 a_column(text) 中国人 ———> 中国,国人,中国人 |
---|
3.聚合练习
#13.聚合之单聚合,统计男女员工各多少人
GET /test/emps/_search
{
"query": {
"match_all": {}
},
"aggs": {
"gendercount": {
"terms": {
"field": "gender.keyword",
"size": 10
}
}
}
}
#14.聚合之先查询再聚合,统计喜欢购物的男女员工各多少人
GET /test/emps/_search
{
"query": {
"match": {
"hobby": "购物"
}
},
"aggs": {
"gendercount": {
"terms": {
"field": "gender.keyword",
"size": 10
}
}
}
}
#15.聚合之多聚合,统计喜欢购物的男女员工各多少人,及这些人总体的平均年龄
GET /test/emps/_search
{
"query": {
"match": {
"hobby": "购物"
}
},
"aggs": {
"gendercount": {
"terms": {
"field": "gender.keyword",
"size": 10
}
},
"avgage":{
"avg": {
"field": "age"
}
}
}
}
#16.聚合之多聚合和嵌套聚合,统计喜欢购物的男女员工各多少人,及这些人不同性别的平均年龄
GET /test/emps/_search
{
"query": {
"match": {
"hobby": "购物"
}
},
"aggs": {
"gendercount": {
"terms": {
"field": "gender.keyword",
"size": 10
},
"aggs": {
"avgage": {
"avg": {
"field": "age"
}
}
}
}
}
}
综合练习
#0.查询的两种方式
# 查询方式一发送REST请求的方式 将请求参数附加在url的后面
GET /test/emps/_search
GET /test/emps/_search?q=*
GET /test/emps/_search?q=age:22
#查询22岁的员工,且按照balance降序排序
GET /test/emps/_search?q=age:22&sort=balance:desc
# 查询方式二,使用ES 的DSL(特定领域语言)语法 ,将请求参数附加在请求体中
GET /test/emps/_search
{
"query": {
"match_all": {}
}
}
#1.全表查询
#2.全表查询,按照年龄降序排序,再按照工资降序排序,只取前5条记录的示empid,age,balance
GET /test/emps/_search
{
"sort": [
{
"age": {
"order": "desc"
}
},
{
"balance": {
"order": "desc"
}
}
],
"from": 0,
"size": 5,
"_source": [
"empid",
"age",
"balance"
]
}
#3.匹配之match(全文检索)分词匹配: 搜索hobby含有吃饭睡觉的员工
#原理:先将查询条件切词,切为 吃饭、睡觉,分别从hobby的倒排索引上
#检索吃饭、睡觉
#where hobby like %吃饭% or hobby like %睡觉%
GET /_analyze
{
"analyzer": "ik_max_word",
"text":"吃饭睡觉"
}
GET /test/emps/_search
{
"query": {
"match": {
"hobby": "吃饭睡觉"
}
}
}
#4.匹配之match/term不分词匹配: 搜索工资是2000的员工
# 2000会不会被切词? 不会!只有text类型能被切词,精确匹配
# balance = 2000 而不是 balance like %2000%
# 在ES中官方建议,在对 text类型进行全文检索时,才用match
# 如果搜索的不是text类型,建议使用term
GET /test/emps/_search
{
"query": {
"match": {
"balance": 2000
}
}
}
# 匹配之term不分词匹配: 搜索工资是2000的员工
GET /test/emps/_search
{
"query": {
"term": {
"balance": 2000
}
}
}
#5.匹配之match不分词匹配: 搜索hobby是吃饭睡觉的员工
# where hobby like %吃饭睡觉%
#keyword类型不切词
GET /test/emps/_search
{
"query": {
"match": {
"hobby.keyword": "吃饭睡觉"
}
}
}
#6.匹配之短语匹配: 搜索hobby是吃饭的员工
GET /test/emps/_search
{
"query": {
"match_phrase": {
"hobby": "吃饭睡觉"
}
}
}
#7.匹配之多字段匹配: 搜索name或hobby中带球的员工
GET /test/emps/_search
{
"query": {
"multi_match": {
"query": "球",
"fields": ["name","hobby"]
}
}
}
#8.匹配之多条件匹配,搜索男性中喜欢购物的员工
GET /test/emps/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"hobby": "购物"
}
},
{
"term": {
"gender": {
"value": "男"
}
}
}
]
}
}
}
#9.匹配之多条件匹配,搜索男性中喜欢购物,还不能爱去酒吧的员工
GET /test/emps/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"hobby": "购物"
}
},
{
"term": {
"gender": {
"value": "男"
}
}
}
],
"must_not": [
{
"match": {
"hobby": "去酒吧"
}
}
]
}
}
}
#10.匹配之多条件匹配,搜索男性中喜欢购物,还不能爱去酒吧的员工,最好在20-30之间
#最好在20-30之间: 如果这个人年龄在20-30之间,优先选择!加分!
#should: 符合条件就加分
GET /test/emps/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"hobby": "购物"
}
},
{
"term": {
"gender": {
"value": "男"
}
}
}
],
"must_not": [
{
"match": {
"hobby": "去酒吧"
}
}
],
"should": [
{
"range": {
"age": {
"gte": 20,
"lte": 30
}
}
}
]
}
}
}
#11.匹配之多条件匹配,搜索男性中喜欢购物,还不能爱去酒吧的员工,最好在20-30之间,不要40岁以上的
GET /test/emps/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"hobby": "购物"
}
},
{
"term": {
"gender": {
"value": "男"
}
}
}
],
"must_not": [
{
"match": {
"hobby": "去酒吧"
}
}
],
"should": [
{
"range": {
"age": {
"gte": 20,
"lte": 30
}
}
}
],
"filter": {
"range": {
"age": {
"lt": 40
}
}
}
}
}
}
#12.匹配之字段模糊联想匹配,搜索Nick
GET /test/emps/_search
{
"query": {
"fuzzy": {
"name": "Dick"
}
}
}