目录
- 传送门
- 前言
- 一、索引(数据库)
- 1、创建索引
- 2、获取索引
- 3、删除索引
- 二、文档(Row行)
- 1、创建文档
- 2、获取文档
- 3、修改文档
- 4、删除文档
- 5、高级查询(精辟)
- 条件查询
- 分页、指定、排序、范围查询
- 全文检索、分组查询等
- match查询
- match_phrase查询
- multi_match查询
- term查询
- terms查询
- fuzzy查询
- range查询
- bool查询
- 排序和分页
- 铁哥小结:
- 三、javaAPI
- 四、系统架构
传送门
SpringMVC的源码解析(精品)
Spring6的源码解析(精品)
SpringBoot3框架(精品)
MyBatis框架(精品)
MyBatis-Plus
SpringDataJPA
SpringCloudNetflix
SpringCloudAlibaba(精品)
Shiro
SpringSecurity
java的LOG日志框架
Activiti(敬请期待)
JDK8新特性
JDK9新特性
JDK10新特性
JDK11新特性
JDK12新特性
JDK13新特性
JDK14新特性
JDK15新特性
JDK16新特性
JDK17新特性
JDK18新特性
JDK19新特性
JDK20新特性
JDK21新特性
其他技术文章传送门入口
前言
ELK设置后抓日志非常好用,当然也不只是用于抓日志。功能强大,全文检索等等。
以下文章不定时更新。
ELK的ElasticStack概念
ELK的ElasticStack语法
ELK的ElasticStack安装
ELK的Logstash
ELK的Kibana
ELK的Filebeat
一、索引(数据库)
1、创建索引
由于没有幂等性,不能用post请求
2、获取索引
url没变,只是改成了get请求
全部索引
3、删除索引
url不变,请求变delete
二、文档(Row行)
1、创建文档
没有表的概念,直接在索引中添加数据。多次执行post请求,返回id不一样。所以post是非幂等性的。(幂等性每次执行都一样的结果),这里也可以用put的
这种是随机id
指定id
2、获取文档
3、修改文档
put是幂等性的(只有post是非幂等,delete、get、head都是幂等),put为全覆盖修改
post局部修改 用_update了
4、删除文档
5、高级查询(精辟)
文档:https://blog.csdn.net/qq_34263207/article/details/127849806
条件查询
q是查询的意思 q=title:华为,就是查询title中有华为字体的所有数据。
这种会把小米手机的也查询出来,应该是包含手机两个字的都出来了。
body方式条件查询
分页、指定、排序、范围查询
请求体 from是从哪一页开始 size是每页大小 下面的数据只显示了2条。
指定分页查询,只显示tilte字段信息出来,其他字段不显示出来。
排序语法,报错了,问题是排序的字段不能是字符串。json的时候 值不要上引号,直接用int类型的数字这种的才行。
这种请求体中 must类似于and,是同时满足的意思
should类似于or,或者的意思
filter过滤,range范围查询,价格大于5000的
全文检索、分组查询等
match就是全文检索
高亮显示
查询结果里面 对查询要高亮显示的字段做了特殊处理
这个会把原始数据也查出
价格size=0,会去掉原始数据,只查询出想要的分组数据
match查询
ES的查询有一个很大的特点就是分词。所以大家在使用ES的过程中脑子要始终有这么一个意识,你要查找的text是通过分词器分过词的,所以你去匹配的实际上是一个个被分词的片段。而你搜索的query也有可能会被分词,match就是一种会将你搜索的query进行分词的查询方法。我们结合例子来看!比如我们要查询的索引结构如下:
{"_index": "textbook","_id": "kIwXeYQB8iTYJNkI986Y","_source": {"bookName": "This is a test doc","author": "老坛","num": 20}
}
_index代表索引名称,_id代表该条数据唯一id,_source代表该条数据具体的结构。这里我们通过bookName字段来查询。输入query语句如下:
GET http://ip:prot/textbook/_search
{"query": {"match": {"bookName":"test"}}
}
该条语句代表用match方式搜索索引为textbook中bookName可以匹配到test的语句。因为:
"bookName": "This is a test doc"
原文被分词器分词后包含test这个词语,所以可以正常被匹配出来。这个例子比较简单,我们换个复杂一点的例子:GET http://ip:prot/textbook/_search
{"query": {"match": {"bookName":"my test"}}
}
大家认为这个能否被匹配出来呢?原文中根本就没有my这个词语,那怎么被匹配出来?但实际上是可以匹配出来的。原因是match查询里,会对你查询的query也进行分词,也就是会将你的"my test"进行分词,得到my与test两个词语,然后用这两个词语分别去匹配文本,发现虽然my匹配不到,但是test可以匹配到,所以依然可以查出来。这个和我们传统的搜索方式确实存在差异,大家要注意。那这种搜索方式存在的价值是什么呢?其实还有蛮大用处的。比如我们的ES库存储的是很多的英文好词好句,然后用户想提高自己的英文写作,因此想搜索出一些比较好的表达加在自己的文章中,那这个时候对于用户来讲,严格的匹配方式大概率什么都搜不到,但是像match这样的搜索方式便非常合适。例如有个好句是这样的:If at first you don't succeed, try again.
然后用户用下面的方式搜索:If you don't success
用match就可以很好的匹配出来。
match_phrase查询
既然match的限制比较小,那如果我们需要这个限制更强一点用什么方式呢?match_phrase便是一个比较不错的选择。match_phrase和match一样也是会对你的搜索query进行分词,但是,不同的是它不是匹配到某一处分词的结果就算是匹配成功了,而是需要query中所有的词都匹配到,而且相对顺序还要一致,而且默认还是连续的,如此一来,限制就更多了。我们还是举个例子。比如还是刚刚的索引数据:{"_index": "textbook","_id": "kIwXeYQB8iTYJNkI986Y","_source": {"bookName": "This is a test doc","author": "老坛","num": 20}
}
如果我们还用刚刚的方式搜索:GET http://ip:prot/textbook/_search
{"query": {"match_phrase": {"bookName":"my test"}}
}
这次是匹配不到结果的。那么怎样才能匹配到结果呢?只能是搜索原文中的连续字串:GET http://ip:prot/textbook/_search
{"query": {"match_phrase": {"bookName":"is a test"}}
}
这样是可以匹配到结果的。但是如此一来限制可能太大了一点,所以官方还给了一个核心餐宿可以调整搜索的严格程度,这个参数叫slop,我们举个例子:GET http://ip:prot/textbook/_search
{"query": {"match_phrase": {"bookName":{"query":"is test","slop":1}}}
}
比如我们将slop置为1,然后搜索"is test",虽然is test中间省略了一个词语"a",但是在slop为1的情况下是可以容忍你中间省略一个词语的,也可以搜索出来结果。以此类推,slop为2就可以省略两个词语了。大家可以根据自己的实际情况进行调整。另外我们可以发现,如果在搜索时添加了辅助参数(比如slop)我们搜索格式的层级要往下扩展一层,之前的"bookName":"my test"
要改为:"bookName":{"query":"is test","slop":1
}
我们注意一下就好了。
multi_match查询
有了前面的基础,multi_match比较好理解。实际上就是可以从多个字段中去寻找我们要查找的query:GET http://ip:prot/textbook/_search
{"query": {"multi_match": {"query" : "老坛","fields" : ["bookName", "author"]}}
}
比如这里我们是从bookName和author两个字段里去寻找老坛,虽然bookName没有,但是author可以匹配到,那也可以找到数据。所以本质上就是对bookName和author分别做了一次match:{"_index": "textbook","_id": "kIwXeYQB8iTYJNkI986Y","_source": {"bookName": "This is a test doc","author": "老坛","num": 20}
}
term查询
term查询也是比较常用的一种查询方式,它和match的唯一区别就是match需要对query进行分词,而term是不会进行分词的,它会直接拿query整体和原文进行匹配。所以不理解的小伙伴使用起来可能会非常奇怪:GET http://ip:prot/textbook/_search
{"query": {"term": {"bookName": "This is a test doc"}}
}
当我们用这种方式进行搜索时,明明要搜索的和被搜索的文本一模一样,确就是搜不出来。这就是因为我们去搜的实际上并不是原文本身,而是被分词的原文,在原文被分好的每一个词语里,没有一个词语是:"This is a test doc",那自然是什么都搜不到了。所以在这种情况下就只能用某一个词进行搜索才可以搜到:GET http://ip:prot/textbook/_search
{"query": {"term": {"bookName": "This"}}
}
terms查询
terms查询事实上就是多个term查询取一个交集,也就是要满足多个term查询条件匹配出来的结果才可以查到,所以是比单纯的term条件更为严格了:GET http://ip:prot/textbook/_search
{"query": {"terms": {"bookName": ["This", "is"]}}
}
比如这个例子,是要求原文中既有This这个词,又有is这个词才可以被查到,那按照这个规则我们是可以匹配到数据的:{"_index": "textbook","_id": "kIwXeYQB8iTYJNkI986Y","_source": {"bookName": "This is a test doc","author": "老坛","num": 20}
}
但是如果改成了一个不存在的词便匹配不到了:GET http://ip:prot/textbook/_search
{"query": {"terms": {"bookName": ["This", "my"]}}
}
fuzzy查询
fuzzy是ES里面的模糊搜索,它可以借助term查询来进行理解。fuzzy和term一样,也不会将query进行分词,但是不同的是它在进行匹配时可以容忍你的词语拼写有错误,至于容忍度如何,是根据参数fuzziness决定的。fuzziness默认是2,也就是在默认情况下,fuzzy查询容忍你有两个字符及以下的拼写错误。即如果你要匹配的词语为test,但是你的query是text,那也可以匹配到。这里无论是错写多写还是少写都是计算在内的。我们同样还是举例说明。对于索引数据:{"_index": "textbook","_id": "kIwXeYQB8iTYJNkI986Y","_source": {"bookName": "This is a test doc","author": "老坛","num": 20}
}
如果查询语句为:GET http://ip:prot/textbook/_search
{"query": {"fuzzy": {"bookName":"text"}}
}
这时肯定是用text来匹配原文中的每一个词,发现text和test最为接近,但是有一个字符的差异,在默认fuzziness为2的情况下,依然可以匹配出来。当然这个fuzziness是可以调的,比如:GET http://ip:prot/textbook/_search
{"query": {"fuzzy": {"bookName":{"value":"texts","fuzziness":1}}}
}
在容忍度为1的情况下,如果你想查texts就查不到结果了。
range查询
range查询时对于某一个数值字段的大小范围查询,比如我这里特意所加的nums字段就是这个时候派上用场的。range的语法设计到了一些关键字:gte:大于等于
gt:大于
lt:小于
lte:小于等于
GET http://ip:prot/textbook/_search
{ "query": {"range": { "num": { "gte":20, "lt":30 } }}
}
比如这样的条件就是去查找字段num大于等于20小于30的数据那我们的数据便可以被查询到:{"_index": "textbook","_id": "kIwXeYQB8iTYJNkI986Y","_source": {"bookName": "This is a test doc","author": "老坛","num": 20}
}
bool查询
bool查询是上面查询的一个综合,它可以用多个上面的查询去组合出一个大的查询语句,它也有一些关键字:
must:代表且的关系,也就是必须要满足该条件
should:代表或的关系,代表符合该条件就可以被查出来
must_not:代表非的关系,也就是要求不能是符合该条件的数据才能被查出来
例如有这样一个查询:GET http://ip:prot/textbook/_search
{"query":{"bool":{"must":{"match":{"bookName":"老坛"}},"should":{"term":{"author":"老坛"},"range":{"num":{"gt":20}},}}}
}
这里就要求must里面的match是必须要符合的,但是should里面的两个条件就可以符合一条即可。
排序和分页
排序和分页也是建立在上述的那些搜索之上的。排序和分页的条件是和query平级去写的,我们一个一个来看。先举个例子:GET http://ip:prot/textbook/_search
{"query":{"match":{"bookName":"老坛"}},"from":0,"size":100,"sort":{"num":{"order":"desc"}}
}
这里关于分页的语句是:"from":0,
"size":100,
它代表的意思是按照页容量为100进行分页,取第一页。关于排序的语句是:"sort":{"num":{"order":"desc"}
}
它需要指定一个字段,然后根据这个字段进行升序或降序。这里我们根据num来进行降序排序,如果想升序就把order的值改为asc就好了。
————————————————
版权声明:本文为CSDN博主「老坛聊开发」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34263207/article/details/127849806
铁哥小结:
比如
后端数据库字段 content存的 this is a test 这句话;这部分我叫做原文部分。
前端有个keyword字段,输入任何内容来查询,下面不同关键字不同情况;这部分我叫做query部分。1、match(对query和原文部分都分词)
当前端输入this,传过来后端就是keyword =this的时候,匹配content字段的话(query=this):
match是把数据库content分词以后去匹配查询,分词后匹配,this可以匹配到,是可以查询到。
当前端输入my this(query=my this):
可以匹配到,因为match不只是对content分词,对你传入的查询条件也分词,my this分词后,里面的this刚好可以匹配到content分词后的this,所以就可以查询到。
2、term(直接拿query整体和原文等于一样的匹配)
当前端输入 this is a test(query=this is a test):
查询不到,因为query部分不会分词,就拿着这句话和原文部分去匹配,但是原文部分在es的作用下分词了,分成了几个不同单词,没有一个单词是能和query部分整句话匹配的,所以查不到。
query=this:
可以查询到,this可以和分词后的原文部分的一个单词匹配成功,就能查询出来。
3、terms(直接拿多个query和原文等于一样的匹配,都成功才能匹配到)
query=[this , a] :
可以查询到,这种是多个部分,this去匹配可以匹配到,a去匹配可以匹配到,整体就能查询出来。
query=[this,b]:
查询不到,this去匹配可以匹配到,b匹配失败,整体就查询失败,查不出。
4、fuzzy(query部分输入的单词有错误也可以像term一样匹配成功)
fuzzy是ES里面的模糊搜索,它可以借助term查询来进行理解。fuzzy和term一样,也不会将query进行分词,但是不同的是它在进行匹配时可以容忍你的词语拼写有错误,至于容忍度如何,是根据参数fuzziness决定的。fuzziness默认是2,也就是在默认情况下,fuzzy查询容忍你有两个字符及以下的拼写错误。即如果你要匹配的词语为test,但是你的query是text,那也可以匹配到。这里无论是错写多写还是少写都是计算在内的。
query=thaa:
可以查询到,默认容忍度=2,少写多写错写两个字母都可以查询到。
query=thisbc :
可以查询到,同上。
5、range(query部分不能和content原文这种比较了,得和num这种数字原文比较大小)
比如 后端数据库字段 num存的 20
数字大于小于匹配的。里面有gte大于等于 lte小于deng gt大于 lt小于。匹配数字的。
query.range.num.lte=30:
可以查询到,这意思query部分是找个小于30的数字
6、bool
bool查询是上面查询的一个综合,它可以用多个上面的查询去组合出一个大的查询语句,它也有一些关键字
must:代表且的关系,也就是必须要满足该条件
should:代表或的关系,代表符合该条件就可以被查出来
must_not:代表非的关系,也就是要求不能是符合该条件的数据才能被查出来
比如 后端数据库字段 age存的10,三个字段content、num、age
query.bool.[must=content.match=this][should=age.lt=30;shoud=num.lt=30]:
可以查询到,写的有点query有点抽象。意思是 must是content字段是this,可以匹配成功,should里面 age或者num小于30任何一个为真,就是真,should和must条件都满足,才能最后查询出来。刚好都满足,可以查出
三、javaAPI
批量插入,后面截图看不到的24行代码参数都是些json串
24行看不到的东西截图
批量删除
条件查询
过滤字段
组合查询
范围查询
模糊查询
高亮查询
聚合查询
分组查询 ageGroup 这种语法
四、系统架构
1、term key:value的精确查询
2、term key:value1,value2的精确查询
3、range gt lt等 范围查询
4、 exists 类似MySQL
5、match 标准查询,包含精确查询和全文查询
6、bool must相当于and must_not相当于not should相当于or
7、filter 过滤查询(普通查询不会缓存更浪费性能,过滤会缓存性能好,而且建议精确查询用过滤并且还能缓存数据)