}
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/8791eb1055ee4ca99fbd37d7351b238e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
之后添加文档,其他英雄的放在附录了,最终的索引应该如下图所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/688c9a80129d48c7aea0953845d2609f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
### 结构化搜索
结构化搜索(Structured search) 是指有关探询那些具有内在结构数据的过程。比如日期、时间和数字都是结构化的:它们有精确的格式,我们可以对这些格式进行逻辑操作。
在结构化查询中,要么存于集合之中,要么存在集合之外。结构化查询**不关心文件的相关度或评分**;它简单的对文档包括或排除处理。
#### 单一过滤器(term)
我们首先来看最为常用的 term 查询, 可以用它处理数字(numbers)、布尔值(Booleans)、日期(date)等。
**注意:ES5.0后,已经没有string类型了**
**警告**:尽量不要用于text类型字段
**查询角色是“法师”的英雄**
GET /heros/_search
{
“query”:{
“term”:{
“role”:“法师”
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/ec7c59df59e14c78b83263f54d963ec2.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
**多个精确值terms**
**查询角色是“法师”或“射手”的英雄**
GET /heros/_search
{
“query”:{
“terms”:{
“role”:[“法师”,“射手”]
}
}
}
结果如图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/926a03e27ebd41e5b6617815f800bb5f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
可以看到,多了射手角色的英雄。
#### 范围过滤器(range)
{
“range”:{
“field_name”:{
},
}
}
对字段进行范围过滤,常用的如下
* gt: > 大于(greater than)
* lt: < 小于(less than)
* gte: >= 大于或等于(greater than or equal to)
* lte: <= 小于或等于(less than or equal to)
**查询19<=age<25的英雄**
GET /heros/_search
{
“query”: {
“range”:{
“age”:{
“gte”:19,
“lt”:25
}
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/b7f3bf5caf5e4d10be59470b7ee7b75d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
#### 组合过滤器(bool过滤器)
将多个过滤器进行组组合
{
“bool” : {
“must” : [],
“must_not” : [],
“should” : [],
“filter”:[],
}
}
* must:所有语句必须匹配,相当于and
* must\_not:所有语句不能匹配,相当于not
* should:至少有一个语句匹配,相当于or
**查询角色是法师或辅助,年龄必须小于20,邮箱不能是新浪邮箱的英雄**
GET /heros/_search
{
“query”: {
“bool”: {
“must”: {
“range”:{
“age”:{
“lt”:20
}
}
},
“must_not”:
{
“match”:{“mail”:“@sina.com”}
},
“should”: [
{
“term”: {“role”: “法师”}
},
{
“term”:{“role”:“辅助”}
}
]
}
}
}
看前面的数据可以发现,就剩大乔了,结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/48681f30f4bc4772ad3869ecb8f89756.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
#### NULL值处理(exists)
**查询有邮箱的英雄**
GET /heros/_search
{
“query”: {
“exists”: {
“field”: “mail”
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/77fb802fc2fa42bc80cb0f14b66ce4b7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
那么,如何查询不存在邮箱的英雄呢?之前有missing,现在不支持了,可以使用must\_not进行嵌套
GET /heros/_search
{
“query”: {
“bool”: {
“must_not”: {
“exists”:{
“field”: “mail”
}
}
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/8214cdc421384db7bdce01d8d1672339.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
### 全文搜索
#### 基于词项与基于全文
如 term 或 fuzzy 这样的底层查询**不需要分析**阶段,它们对单个词项进行操作。
像 match 或 query\_string 这样的查询是高层查询,它们了解字段映射的信息
#### 匹配搜索(match)与操作符(operator)
**查询sentence中含诗的英雄**
GET /heros/_search
{
“query”: {
“match”: {
“sentence”: “诗”
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/c140e8e289bf4aecac816c678c0e65df.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
可以看到,评分语句更短的评分更高
**多词搜索**情况下
**查询sentence中含“我 诗”的英雄**
GET /heros/_search
{
“query”: {
“match”: {
“sentence”: “我 诗”
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/bac0ecd5370648cfb5167711bdd9329d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
可以看到有些只包含我或诗的内容也出来了,虽然排名落后,如何做到**且**呢,前面使用了must,这里使用operator实现
GET /heros/_search
{
“query”: {
“match”: {
“sentence”: {
“query”: “我 诗”,
“operator”: “and”
}
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/684b05f7206c4534a39b8de5510cdf4b.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
#### 权重提升(boost)
**查询sentence中必须包含"Whenever",有"in"或者"be"的英雄**
GET /heros/_search
{
“query”: {
“bool”: {
“must”: [
{“match”: {
“sentence”: “Whenever”
}}
],
“should”: [
{ “match”: { “sentence”: “in” }
},
{ “match”: { “sentence”: “be” }}
]
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/f40aca1c290546869464ddff4ab2c037.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
现要求**含in的权重更高**,也就是提高\_score来提高搜索排名
boost默认为1,通过增加in的boost来提高in的排名
GET /heros/_search
{
“query”: {
“bool”: {
“must”: [
{“match”: {
“sentence”: “Whenever”
}}
],
“should”: [
{ “match”: {
“sentence”: {
“query”: “in”,
“boost”: 2
}
}
},
{ “match”: { “sentence”: “be” }}
]
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/893053feb2a0446f9d8fbc4328cec776.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
### 多字段搜索
前面已经进行了简单的多字符串搜索,不过,还有一些多字段时复杂的搜索情况。
#### 最佳字段查询(dis\_max与tie\_breaker)
**查询爱好有诗,sentence(随便起的名字,可以理解为个性签名或一句话介绍)中有诗或她的英雄**
GET /heros/_search
{
“query”: {
“bool”: {
“should”: [
{ “match”: { “hobby”: “诗” }},
{ “match”: { “sentence”: “诗 她” }}
]
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/fadabd2e3bae4e86b77fbc23cc5c396d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
可以看到,第二个结果是我们更想得到的。bool会打两次分,再除以语句总数2,第一个结果hobby和sentence都有诗,导致第一个结果就靠前了,由于hobby和sentence的竞争关系,所以需要找到最佳匹配字段。
使用dis\_max来得到想要的结果
GET /heros/_search
{
“query”: {
“dis_max”: {
“queries”: [
{ “match”: { “hobby”: “诗” }},
{ “match”: { “sentence”: “诗 她” }}
]
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/43a7f11cbc7440f6a88e77e76cc7eab9.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
tips:想要在bool和dis\_max之间,可以使用tie\_breaker参数,请读者自行深入了解。
#### 多字段进行相同搜索(multi\_match)
**查询hobby或sentence中含诗的英雄**,也就是对hobby sentence做同一搜索,如果写多个match会比较繁琐,可以采用multi\_match,字段使用列表的方式填写多个即可。
GET /heros/_search
{
“query”: {
“multi_match”: {
“query”: “诗”,
“fields”: [“hobby”,“sentence”]
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/4d25e37f7f3546799c0f23bdd3641d8c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
hobby和sentence都含诗的会排名靠前
### 部分匹配
即只输入一部分,也能匹配到,最经典的就是边输入边搜索,也。
#### 输入即搜索(match\_phrase\_prefix)
现在很多搜索引擎都有用户边输入边提示的功能,不必等用户Enter,提高了用户体验
**用户查询sentence,输入了when,查询此时的下拉框的结果**
GET /heros/_search
{
“query”: {
“match_phrase_prefix”: {
“sentence”: {
“query”: “When”
}
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/c8a96dd7012840d28f40be80b2fa0377.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
#### 通配符搜索(wildcard)
包含两个通配符"?“和”\*",? 匹配任意字符, \* 匹配 0 或多个字符
**搜索姓孙的英雄**
GET /heros/_search
{
“query”: {
“wildcard”: {
“name”: “孙*”
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/d7c1bc55c8d543e28bda44d0ab2f9bfc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
#### 正则表达式搜索(regexp)
正则表达式更加的丰富,包含数字、特殊字符等
**搜索邮箱含s、n,s在n前面的英雄**
GET /heros/_search
{
“query”: {
“regexp”: {
“mail”: “s.*n.*”
}
}
}
结果如下图所示
![在这里插入图片描述](https://img-blog.csdnimg.cn/cdbc554b696c4e1698eac16a3c7ecd43.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbGFkeV9raWxsZXI5,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
sunce符合,新浪邮箱也符合。
## 总结
本文讲了一些基础概念,深入研究了一些搜索(抛转引玉,官网还有很多搜索方式),本来想写集群的,白嫖腾讯云的只能固定三个节点,没法演示扩容之类的,下篇文章再说一下集群。
**练习**
查询角色是“坦克”的英雄?
查询年龄>18的“法师”英雄?
查询姓"孙"的且名字是两个字的英雄?
## 附录
POST /heros/_doc/1002
{
“name”:“小乔”,
“age”:19,
“role”:“法师”,
“birthday”:“2002-01-20”,
“mail”:“xiaoqiao@sina.com”,
“hobby”:“画画 唱歌”,
“sentence”:“Whenever you need me, I’ll be here.”
}
POST /heros/_doc/1003
{
“name”:“孙策”,
“age”:25,
“role”:“坦克”,
“birthday”:“1996-11-10”,
“mail”:“sunce@163.com”,
“hobby”:“画画 唱歌”,
“sentence”:“我向往诗和远方,也不会忘记她和故乡”
}
POST /heros/_doc/1004
{
“name”:“周瑜”,
“age”:23,
“role”:“法师”,
“birthday”:“1998-01-20”,
“mail”:“zhouyu@sina.com”,
“hobby”:“写诗 画画”,
“sentence”:“Whenever you are in trouble,I’m always near.”
}
POST /heros/_doc/1005
{
“name”:“刘备”,
“age”:30,
“role”:“打野”,
“birthday”:“1991-10-20”,
“mail”:“liubei@qq.com”,
“hobby”:“兵法 武器”,
“sentence”:“Shi wo bu tai dong”
}
## 写在最后
**在结束之际,我想重申的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。**
需要完整版PDF学习资源私我
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**