ElasticSearch搜索引擎使用指南

一、ES数据基础类型

1、数据类型

字符串

主要包括: text和keyword两种类型,keyword代表精确值不会参与分词,text类型的字符串会参与分词处理

数值

包括: long, integer, short, byte, double, float

布尔值

boolean

时间

date

数组

数组类型不需要专门定义,只要插入的字段值是json数组就行

GEO类型

主要涉及地理信息检索、多边形区域的表达

2、text&keyword使用注意

text类型,支持全文搜索,因为text涉及分词,所以可以配置使用什么分词器,尤其涉及中文分词。

实际项目中,如果不需要模糊搜索的字符类型,可以选择keyword类型,例如:手机号、email、微信的openid等等,如果选text类型,可能会出现搜出一大堆相似的数据,而且不是精确的数据。

二、query语法

query子句主要用于编写查询条件,类似于SQL中的where语句。

query子句主要用于编写类似SQL的where语句,支持布尔查询(and/or)、IN、全文搜索、模糊匹配、范围查询(大于/小于)。

其中:text类型字段支持分词,可以使用模糊查询。keyword类型只能做等值查询,不能进行分词。

1、match类like匹配

1.1 match匹配单个字段

使用match实现全文搜索。类似于SQL中的like操作。

简单使用的语法:

GET /{索引名}/_search
{
  "query": {
    "match": {
      "{FIELD}": "{TEXT}"
    }
  }
}

说明:
{FIELD} - 就是我们需要匹配的字段名
{TEXT} - 就是我们需要匹配的内容

例子:

GET /article/_search
{
    "query": {
        "match" : {
            "title" : "ES教程"
        }
    }
}

article索引中,title字段匹配“ES教程”的所有文档。

如果title字段的数据类型是text类型,搜索关键词会进行分词处理。

等价SQL(假设"ES教程"没有进行分词):

select * from article where title like '%ES教程%'

1.2 multi_match多字段匹配

例子:

GET /article/_search
{
  "query": {
    "multi_match": {
      "query": "斯柯达前轮制动器",
      "fields":[
        "doc_title",
        "doc_content"
      ]
    }
  }
}

等价SQL:

select * from article where doc_title like '%<斯柯达前轮制动器的分词>%' or doc_content like '%<斯柯达前轮制动器的分词>%'

因为 斯柯达前轮制动器的分词 会有很多,所以实际上也会有很多的like,而不仅仅是上面的两个like。

1.3 multi_phrase顺序匹配

match_phrase查询是ES中一种用于精确匹配短语的查询方式,可以确保查询字符串中的关键词按照给定的顺序在文档中连续出现。

说明:检索词还是进行分词的,分词后的各个单词的顺序在 被检索的文中是一样的。

例子:

GET /article/_search
{
  "query": {
    "match_phrase": {
      "doc_content": "制动器装配"
    }
  }
}

搜索结果:

1.4 operator的布尔操作 

指定分词匹配的布尔规则,默认情况下operator为or,即分词中有一个匹配即可。

当operator为and时,需要文档匹配所有的分词。

例子:

GET demo_idx/_search
{
  "query": {
    "match": {
      "content": {
        "query": "simple rest apis distributed nature",
        "operator": "and"
      }
    }
  }
}

1.5 结合operator、boost及match_phrase的查询

我们希望精确匹配在搜索结果中排名较高,但也希望看到结果中相关性较低的文档,此时使用should子句来组合OR、AND和match短语查询。布尔查询中的should子句采用更好匹配的方法,因此每个子句的得分将为每个文档的最终_score做出贡献。

GET demo_idx/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "content": {
              "query": "simple rest apis distributed nature"
            }
          }
        },
        {
          "match": {
            "content": {
              "query": "simple rest apis distributed nature",
              "operator": "and"
            }
          }
        },
        {
          "match_phrase": {
            "content": {
              "query": "simple rest apis distributed nature",
              "boost": 2
            }
          }
        }
      ]
    }
  }
}

2、term精确匹配单个字段

使用term实现精确匹配

如果想要类似SQL语句中的等值匹配,不需要进行分词处理,例如:订单号、手机号、时间字段,不需要分值处理,只要精确匹配。

语法:

GET /{索引名}/_search
{
  "query": {
    "term": {
      "{FIELD}": "{VALUE}"
    }
  }
}

{FIELD} - 就是我们需要匹配的字段名
{VALUE} - 就是我们需要匹配的内容,除了TEXT类型字段以外的任意类型

例子:

GET /order_v2/_search
{
  "query": {
    "term": {
      "order_no": "202003131209120999"
    }
  }
}

搜索订单号order_no = "202003131209120999"的文档。

类似SQL语句:

select * from order_v2 where order_no = "202003131209120999"

3、terms实现SQL的in语句

如果我们要实现SQL中的in语句,一个字段包含给定数组中的任意一个值就匹配。

语法:

GET /order_v2/_search
{
  "query": {
    "terms": {
      "{FIELD}": [
        "{VALUE1}",
        "{VALUE2}"
      ]
    }
  }
}

说明:

{FIELD} - 就是我们需要匹配的字段名
{VALUE1}, {VALUE2} … {VALUE N} - 就是我们需要匹配的内容,除了TEXT类型字段以外的任意类型。

例子:

GET /order_v2/_search
{
  "query": {
    "terms": {
      "shop_id": [123,100,300]
    }
  }
}

搜索order_v2索引中,shop_id字段,只要包含[123,100,300]其中一个值,就算匹配。

类似SQL语句:

select * from order_v2 where shop_id in (123,100,300)

4、range范围查询

通过range实现范围查询,类似SQL语句中的>, >=, <, <=表达式。

语法:

GET /{索引名}/_search
{
  "query": {
    "range": {
      "{FIELD}": {
        "gte": 10, 
        "lte": 20
      }
    }
  }
}

参数说明:

{FIELD} - 字段名

gte范围参数 - 等价于>=

lte范围参数 - 等价于 <=

范围参数可以只写一个,例如:仅保留 “gte”: 10, 则代表 FIELD字段 >= 10

范围参数如下:

gt - 大于 ( > )
gte - 大于且等于 ( >= )
lt - 小于 ( < )
lte - 小于且等于 ( <= )

例子:

GET /order_v2/_search
{
  "query": {
    "range": {
      "shop_id": {
        "gte": 10,
        "lte": 200
      }
    }
  }
}

查询order_v2索引中,shop_id >= 10 且 shop_id <= 200的文档。类似SQL:

select * from order_v2 where shop_id >= 10 and shop_id <= 200

5、bool组合查询

前面的例子都是设置单个字段的查询条件,如果想要编写类似SQL的Where语句组合多个字段的查询条件,可以使用bool语句。

5.1 bool查询基本语法结构

语法:

GET /{索引名}/_search
{
  "query": {
    "bool": { // bool查询
      "must": [], // must条件,类似SQL中的and, 代表必须匹配条件
      "must_not": [], // must_not条件,跟must相反,必须不匹配条件
      "should": [] // should条件,类似SQL中or, 代表匹配其中一个条件
    }
  }
}

must、must_not和should条件的参数都是一个数组,意味着他们都支持设置多个条件。

同时,前面介绍的单个字段的匹配语句,都可以用在bool查询语句中进行组合。

5.2 must条件

类似SQL的and,代表必须匹配的条件。

语法:

GET /{索引名}/_search
{
  "query": {
    "bool": {
      "must": [
         {匹配条件1},
         {匹配条件2},
         ...可以有N个匹配条件...
        ]
    }
  }
}

例子:

GET /order_v2/_search
{
  "query": {
    "bool": {
      "must": [
          {
            "term": {
              "order_no":  "202003131209120999"
            }
          },
          {
            "term": {
              "shop_id":  123
            }
          }
        ]
    }
  }
}

这里的Must条件,使用了term精确匹配,等价SQL:

select * from order_v2 where order_no="202003131209120999" and shop_id=123

5.3 must_not条件

跟must的作用相反,语法类似。

5.4 should条件

类似SQL中的 or, 只要匹配其中一个条件即可。

语法:

GET /{索引名}/_search
 {
   "query": {
     "bool": {
       "should": [
          {匹配条件1},
          {匹配条件2},
          …可以有N个匹配条件…
         ]
     }
   }
 }

例子:

GET /order_v2/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "order_no": "202003131209120999"
          }
        },
        {
          "term": {
            "order_no": "22222222222222222"
          }
        }
      ]
    }
  }
}

等价SQL:

select * from order_v2 where order_no="202003131209120999" or order_no="22222222222222222"

5.5 bool综合例子

GET /order_v2/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "order_no": "2020031312091209991"
                }
              },
              {
                "range": {
                  "shop_id": {
                    "gte": 10,
                    "lte": 200
                  }
                }
              }
            ]
          }
        },
        {
          "terms": {
            "tag": [
              1,
              2,
              3,
              4,
              5,
              12
            ]
          }
        }
      ]
    }
  }
}

等价SQL:

select * from order_v2 where (order_no='202003131209120999' and (shop_id>=10 and shop_id<=200)) or tag in (1,2,3,4,5)

6、wildcard通配符查询

wildcard 关键字: 通配符查询 ? 用来匹配一个任意字符 * 用来匹配多个任意字符。

例子:

GET /xizi/emp/_search
    {
      "query": {
        "wildcard": {
          "name": {
            "value": "xi*"
          }
        }
      }
    }

7、fuzzy模糊查询

fuzzy 模糊查询,最大模糊错误必须在0-2之间  

搜索关键词长度为 2 不允许存在模糊 0

 搜索关键词长度为3-5 允许一次模糊 0 1  

搜索关键词长度大于5 允许最大2模糊

例子:

GET /xizi/emp/_search
    {
      "query": {
        "fuzzy": {
          "name":"xizi"
        }
      }
    }

8、额外限制条件

8.1 _source指定返回字段

例子1:

get lib3/user/_search
{
  "_source":["name","age"],
  "query":{
    "match": {
      "interests": "changge"
    }
  }

结果只返回索引中name和age字段信息

例子2:

get lib3/user/_search
{
  "query":{
    "match_all": {}
  },
  "_source":{
     "includes": "addr*",
     "excludes": ["name","bir*"]
  }
}

显示要的字段、去除不需要的字段、可以使用通配符*。

8.2 boost查询的权重

boost值控制每个查询子句的相对权重,该值默认为1。

boost参数被用来增加一个子句的相对权重(当boost大于1时),或者减小相对权重(当boost介于0到1时),但是增加或者减小不是线性的。换言之,boost设为2并不会让最终的_score加倍。

例子:

GET/_search{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "content": {
                        "query": "full text search",
                        "operator": "and"
                    }
                }
            },
            "should": [{
                "match": {
                    "content": {
                        "query": "Elasticsearch",
                        "boost": 3
                    }
                }
            },
            {
                "match": {
                    "content": {
                        "query": "Lucene",
                        "boost": 2
                    }
                }
            }]
        }
    }
}

8.3 min_similarity设置匹配的最小相似度

8.4 highlight高亮搜索结果

例子:

get data_info/_search
{
  "_source":["doc_title","doc_content"],
  "query": {
    "match": {
      "doc_content": "斯柯达前轮制动器"
    }
  },
  "highlight":{
    "fields":{
      "doc_content":{}
    }
  }
}

返回结果:

8.5 size指定返回条数

ES默认返回10条结果。

例子:

get data_info/_search
{
  "query": {
    "match": {
      "doc_content": "斯柯达前轮制动器"
    }
  },
  "size": 2
}

结果中只有2条信息。

8.6 from分页查询

from 关键字: 用来指定起始返回位置,和size关键字连用可实现分页效果。

例子:

get data_info/_search
{
  "query": {
    "match": {
      "doc_content": "斯柯达前轮制动器"
    }
  },
  "size": 2,
  "from": 3
}

8.7 sort指定字段排序

使用该属性会让得分失效

例子:

GET /db_idx4/_search
{
    "query":{
        "match_all":{

        }
    },
    "sort":[
        {
            "age":"desc"
        }
    ]
}

8.8 explain查看分数计算详情

ES提供了一个解释性API和一个解释性查询参数以了解如何计算分数。

例子:

GET /db_idx4/_search
{
  "explain": true,
  "query": {
    "match_phrase": {
      "doc_content": "制动器装配"
    }
  }
}

结果示例:

三、全文搜索

1、概念

平时我们使用SQL like语句搜索一些文本、字符串是否包含指定的关键词,如果两篇文章都包含我们的关键词,那么具体哪篇文章内容的相关度更高?这个SQL的like语句是做不到的,更别说like语句的性能问题了。

ES通过分词、相关度计算可以解决这个问题,ES内置了一些相关度算法,大致上意思是:如果一个关键词在一篇文章出现的频率高,并且在其他文章中出现少,那说明这个关键词与这篇文章的相关度很高。

ES对于text类型的字段,在插入数据的时候,会进行分词处理,然后根据分词的结果索引文档,当我们搜索text类型字段的时候,也会先对搜索关键词进行分词处理、然后根据分词的结果去搜索。

2、文档评分计算

2.1 默认评分影响因素

ES使用的默认评分算法是BM25,决定文档得分的3个主要因素:

  • 字词频率(TF):搜索字词在我们正在搜索的文档中的字段中出现的次数越多,则该文档越相关
  • 反向文档频率(IDF):在我们要搜索的字段中包含搜索词的文档越多,该词的重要性就越低
  • 字段长度:如果文档在非常短的字段(即,只有几个单词)中包含搜索词,则比文档在较长的字段(即,包含很多单词)中包含搜索词更相关

2.2 使用function_score和script_score定制搜索结果分数

function_score和script_score是很耗资源的,所以实际使用时只需要计算一组经过过滤的文档的分数。

script_score定制的例子:

GET best_games/_search
{
  "_source": [
    "name",
    "critic_score",
    "user_score"
  ],
  "query": {
    "script_score": {
      "query": {
        "match": {
          "name": "Final Fantasy"
        }
      },
      "script": {
        "source": "_score * (doc['user_score'].value*10+doc['critic_score'].value)/2/100"
      }
    }
  }
}

具体细节参考:Elasticsearch:使用 function_score 及 script_score 定制搜索结果的分数-CSDN博客

 

3、分词效果测试

语法:

GET /_analyze
{
  "text": "需要分词的内容",
  "analyzer": "分词器"
}

例子:

GET http://xx.elasticsearch.aliyuncs.com:9200/_analyze
{
	"text":"上海大学",
	"analyzer": "standard"
}

使用standard分词器,对"上海大学"进行分词,下面是输出结果:

{
	"tokens": [
		{
			"token": "上",
			"start_offset": 0,
			"end_offset": 1,
			"type": "<IDEOGRAPHIC>",
			"position": 0
		},
		{
			"token": "海",
			"start_offset": 1,
			"end_offset": 2,
			"type": "<IDEOGRAPHIC>",
			"position": 1
		},
		{
			"token": "大",
			"start_offset": 2,
			"end_offset": 3,
			"type": "<IDEOGRAPHIC>",
			"position": 2
		},
		{
			"token": "学",
			"start_offset": 3,
			"end_offset": 4,
			"type": "<IDEOGRAPHIC>",
			"position": 3
		}
	]
}

token就是分解出来的关键词。

四、难点剖析

1、filter与must的区别

同样是按条件匹配,filter不统计相关度,must统计相关度。就是filter不计算score分数值,而must是计算的。所以must比filter计算更复杂、更耗时。

具体参考:Elasticsearch Query: filter与must的区别_elasticsearch must 和filter的区别-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/420159.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

汽车三元催化器的废品项目详解,三元催化再生项目的回收技术教学

一、教程描述 这是一个收废品项目&#xff0c;就收那些别人不懂的&#xff0c;三元催化器的附加值高&#xff0c;只要掌握技术&#xff0c;怎么玩都行的&#xff0c;只是要放得下你的面子。三元催化器&#xff0c;是安装在汽车排气系统中最重要的机外净化装置&#xff0c;它可…

CodeWhisperer安装教导--一步到位!以及本人使用Whisperer的初体验。

CodeWhisperer是亚马逊出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。类似 Cursor 和Github AWS CodeWhisperer 亚马逊科技的CodeWhisperer是Amazon于2021年12月推出的一款代码补全工具&#xff0c;与GitHub Copilot类似。主要的功能有:代码补全注释…

网络编程学习

思维导图 代码练习 TCP实现通信 服务器端代码 #include <myhead.h> #define SER_IP "192.168.152.135" #define SER_PORT 8910 int main(int argc, const char *argv[]) {//&#xff11;创建用于监听的套接字int sfd -1;sfd socket(AF_INET,SOCK_STREAM,0)…

python中自定义报错

class MyError(Exception):def __init__(self,num):#录入的数Exception.__init__(self)self.numnumdef __str__(self):return 这是我定义的第%d个异常 %(self.num)使用 try:raise MyError(4) except MyError as e:print(e)raise 其作用是指定抛出的异常名称&#xff0c;以及异常…

【c++】通讯录管理系统

1.系统功能介绍及展示 2.创建项目 3.菜单实现 4.退出功能实现 5.添加联系人—结构体设计 6.添加联系人—功能实现 7.显示联系人 8.删除练习人—检测联系人是否存在 9.删除联系人—功能实现 10.查找联系人 11.修改联系人 12.清空通讯录 #include <iostream> #include <…

JavaScript类型转换

一些需要注意的数据类型&#xff1a; NaN的数据类型是numberArray、Date、null的数据类型是object未定义变量的数据类型是undefined 自动转换类型&#xff1a;尝试操作一个 “错误” 的数据类型时&#xff0c;会自动转换为 “正确” 的数据类型。 5 null // 返回 5 …

百度测试经理,对自动化测试初学者的一些忠告

前言 相信很多的测试人员都有这样的顾虑&#xff0c;初学自动化测试应该怎么去做&#xff0c;那么现在我就把我在百度测试岗学到的经验分享给大家&#xff0c;希望对你们有帮助。 为了大家在学习的道路上更加轻松&#xff0c;我还给大家整理了一套Python自动化测试学习资料以…

Vue全家桶:vue2+vue3全部搞懂:第五篇,Vue的watch监视器

前提&#xff0c;建议先学会前端几大基础&#xff1a;HTML、CSS、JS、Ajax&#xff0c;不然不好懂 这一专栏知识将一次性将vue、vue2、vue3全部讲明白 一、何为watch监视器 其实我个人理解&#xff0c;就跟原本的表单的input事件一样&#xff0c;实时监视事件发生并同步更新数…

RuoYi-Vue-Plus功能分析-jackson配置

文章目录 前言一、配置文件二、配置类三、注解四、json工具类1. 工具内容2. 使用工具 前言 前端在给我发送请求的时候一般包含三个部分url&#xff0c;header&#xff0c;body。那么就会涉及我们后端如何接收这些请求参数并且我们处理完毕参数后前端又如何接收参数 通过url传…

【python】json转成成yaml中文编码异常显示成:\u5317\u4EAC\u8DEF123\u53F7

姊妹篇&#xff1a;【python】json转成成yaml json数据 {"name": "张三","age": 30,"isMarried": false,"children": [{"name": "小王","age": 5},{"name": "小李",&qu…

装饰器模式 详解 设计模式

装饰器模式 它允许你在不改变对象结构的情况下&#xff0c;动态地将新功能附加到对象上。 结构&#xff1a; 抽象组件&#xff08;Component&#xff09;&#xff1a;定义了原始对象和装饰器对象的公共接口或抽象类&#xff0c;可以是具体组件类的父类或接口。具体组件&…

算法--动态规划(线性DP、区间DP)

这里写目录标题 tip数组下标从0开始还是从1开始 线性DP数学三角形介绍算法思想例题代码 最长上升子序列介绍算法思想例题代码 最长公共子序列介绍算法思想例题代码 编辑距离介绍例题代码 区间DP问题石子合并介绍算法思想例题代码 tip 数组下标从0开始还是从1开始 如果代码中涉…

Topaz Video AI:一键提升视频品质,智能重塑影像魅力 mac/win版

Topaz Video AI是一款革命性的视频智能处理软件&#xff0c;它利用先进的机器学习和人工智能技术&#xff0c;为视频创作者提供了前所未有的视频增强和修复功能。无论您是专业视频编辑师、摄影师&#xff0c;还是热爱视频创作的爱好者&#xff0c;Topaz Video AI都能帮助您轻松…

返回JSON对象

在目前的Java项目中&#xff0c;我们最经常使用的便是JSON&#xff0c;不是传递JSON对象&#xff0c;就是返回JSON对象&#xff0c;甚至还把多个参数封装成JSON对象来进行传递&#xff0c;以便简化代码等&#xff01; 但是&#xff0c;该如何操作代码才能正确的返回一个或者多…

excel导出标准化

虽然标题叫标准化&#xff0c;只不过是我自己的习惯&#xff0c;当一件事情变得流程标准化之后&#xff0c;开发程序就会飞快&#xff0c;开发评估工作总是 搞个1~2天&#xff0c;实则前端后端一起开发&#xff0c;1个小时就可以搞定。 1 前端 const exportXls async () >…

每日一题——LeetCode1556.千位分隔符

方法一 个人方法&#xff1a; 把n转为字符串&#xff0c;逆序遍历n&#xff0c;把n的每个元素加入res&#xff0c;每三次加入.&#xff0c;最后将res翻转再转为字符串即为符合题目要求的结果 var thousandSeparator function(n) {nlet res[],lenn.length-1for(let ilen;i>…

tomcat 搭建博客 及破解数据库密码

一 tomcat 搭建博客 &#xff08;一&#xff09;博客安装包 1&#xff0c; 把博客war包 放到 webapps 文件夹下 2&#xff0c;会自动解压 3&#xff0c;做个软连接 方便后续操作 可以注意到 因为war包 是又tomcat 自己解压的 所以属主数组还是 tomcat &#xff08…

大模型生成,Open API调用

大模型是怎么生成结果的 通俗原理 其实&#xff0c;它只是根据上文&#xff0c;猜下一个词&#xff08;的概率&#xff09;…… OpenAI 的接口名就叫【completion】&#xff0c;也证明了其只会【生成】的本质。 下面用程序演示【生成下一个字】。你可以自己修改 prompt 试试…

LaMa Image Inpainting 图像修复 Onnx Demo

目录 介绍 效果 模型信息 项目 代码 下载 LaMa Image Inpainting 图像修复 Onnx Demo 介绍 gihub地址&#xff1a;https://github.com/advimman/lama &#x1f999; LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WAC…

电脑休眠之后唤不醒

现象&#xff1a;午休时间电脑休眠了&#xff0c;醒来之后发现在密码输入界面&#xff0c;但鼠标键盘没反应。按重启键或电源机重新开机&#xff0c;结果开不了机。 原因&#xff1a;1、内存条脏了&#xff0c;导致内存条读取失败 2、休眠的时候硬盘休眠了&#xff0c;导致按…