SpringCloud学习路线(11)——分布式搜索ElasticSeach场景使用

一、DSL查询文档

(一)DSL查询分类

ES提供了基于JSON的DSL来定义查询。

1、常见查询类型:

  • 查询所有: 查询出所有的数据,例如,match_all
  • 全文检索(full text)查询: 利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:
    • match_query
    • multi_match_query
  • 精确查询: 根据精确词条值查找数据,一般查找精确值,例如:
    • ids
    • range
    • term
  • 地理(geo)坐标查询: 根据经纬度查询,例如:
    • geo_distance
    • geo_bounding_box
  • 复合(compound)查询: 复合查询可以将伤处查询条件组合起来,合并查询条件,例如:
    • bool
    • function_score

2、查询的基本语法

GET /indexName/_search
{"query": {"查询类型": {"查询条件": "条件值"}}
}

3、match_all的使用

GET /indexName/_search
{"query": {"match_all": { }}
}

查询效果

{"took" : 446,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "test","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"info" : "这是我的ES拆分Demo","age" : 18,"email" : "zengoo@163.com","name" : {"firstName" : "Zengoo","lastName" : "En"}}}]}
}

(二)全文检索查询

全文检索查询,会对用户输入内容分词,常用于搜索框搜索。

1、match查询

(1)结构

GET /indexName/_search
{"query": {"match": { "FILED": "TEXT"}}
}

(2)简单使用

GET /test/_search
{"query": {"match": { "info": "ES"  #当有联合属性all,进行匹配,就可以进行多条件匹配,按照匹配数量来确定权值大小。}}
}

使用结果

{"took" : 71,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 0.2876821,"hits" : [{"_index" : "test","_type" : "_doc","_id" : "1","_score" : 0.2876821,"_source" : {"info" : "这是我的ES拆分Demo","age" : 18,"email" : "zengoo@163.com","name" : {"firstName" : "Zengoo","lastName" : "En"}}}]}
}

2、multi_match查询

从使用效果上,与条件查询的"all"字段相同。

(1)结构

GET /indexName/_search
{"query": {"multi_match": { "query": "TEXT","fields": ["FIELD1", "FIELD2"]}}
}

(2)简单使用

GET /test/_search
{"query": {"multi_match": {"query": "ES","fields": ["info","age"]}}
}

(三)精准查询

精确查询一般是查找精确值,所以不会对搜索条件分词。

1、term: 根据词条精确值查询,在商城项目中,通常会用在类型筛选上。

(1)结构

GET /test/_search
{"query": {"term": {"FIELD": {"value": "VALUE"}}}
}

(2)简单使用

GET /test/_search
{"query": {"term": {"city": {"value": "杭州" #精确值}}}
}

2、range: 根据值范围查询,在商城项目中,通常会用在价值筛选上。

(1)结构

GET /test/_search
{"query": {"range": {"FIELD": {"gte": 10,"lte": 20}}}
}

(2)简单使用

GET /test/_search
{"query": {"range": {"price": {"gte": 699, #最低值,gte 大于等于,gt 大于"lte": 1899 #最高值,lte 小于等于,lt 小于}}}
}

(四)地理坐标查询

1、geo_distance: 查询到指定中心小于某个距离值的所有文档(圆形范围圈)。

(1)结构

GET /indexName/_search
{"query": {"geo_distance": {"distance": "15km","FIELD": "13.21,121.5"}}
}

(2)简单使用

GET /test/_search
{"query": {"geo_distance": {"distance": "20km","location": "13.21,121.5"}}
}

2、geo_bounding_box: 查询geo_point值落在某个举行范围的所有文档(矩形范围圈)。

(1)结构

GET /indexName/_search
{"query": {"geo_bounding_box": {"FIELD": {"top_left": {"lat": 31.1,"lon": 121.5},"bottom_right": {"lat": 30.9,"lon": 121.7}}}}
}

(五)复合查询

复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑。

1、function score: 算分函数查询,可以控制文档相关性算分,控制文档排名。

当我们利用match查询时,文档结果会根据搜索词条的关联度打分(_score),返回结果时按照分值降序排列。
例如,在搜索CSDNJava。

[{"_score": 17.85048,"_source": {"name": "Java语法菜鸟教程"}},{"_score": 12.587963,"_source": {"name": "Java语法W3CScool"}},{"_score": 11.158756,"_source": {"name": "CSDNJava语法学习树"}},
]

相关算法:

  • 最开始的算分算法:TF(词条频率) = 词条 / 文档词条总数
  • 避免公共词条改良的算分算法:TF-IDF算法
    • IDF(逆文档频率) = Log( 文档总数 / 包含词条的文档总数 )
    • socre = (∑(i,n) TF) * IDF
  • BM25算法: 现在默认采用的算法,该算法比较复杂,其词频曲度最终会趋于水平。

(1)结构

GET /hotel/_search
{"query": {"function_socre": {    #查询类型"query": {  #查询原始数据"match": {"all": "外滩"}},"functions": [  #解析方法{"filter": {     # 过滤条件"term": {"id": "1"}},"weight": 10  # score算分方法,weight是直接以常量为函数结果,其它的还有feild_value_factor:以某字段作为函数结果,random_score: 随机值作为函数结果,script_score:定义计算公式}],"boost_mode": "multiply"  # 加权模式,定义function score 与 query score的运算方式,包括 multiply:两者相乘(默认);replace:用function score 替换 query score;其它: sum、avg、max、min}}
}

(2)简单使用

需求: 将用户给的词条排名靠前

需要考虑的元素:

  • 哪些文档需要算分加权 : 包含词条内容的文档
  • 算分函数是什么: weight
  • 加权模式用哪个: sum

实现:

GET /hotel/_search
{"query": {"function_socre": {	# 算分算法"query": {"match": {"all": "速8快捷酒店"}},"functions": [ {"filter": {	# 满足条件,品牌必须是速8"term": {"brand": "速8"}},"weight": 2  #算分权重为 2}],"boost_mode": "sum"}}
}

2、复合查询 Boolean Query

子查询的组合方式:

  • must: 必须匹配每个子查询,类似 “与”
  • should: 选择性匹配子查询,类似 “或”
  • must_not: 排除匹配模式,不参与算分,类似 “非”
  • filter: 必须匹配,不参与算分

实现案例

#搜查位置位于上海,品牌为“皇冠假日”或是“华美达”,并且价格500<price<600元,且评分大于等于45的酒店
GET /hotel/_search
{"query": {"bool": {"must": [	# 必须匹配的条件{ "term": { "city: "上海" } }],"should": [	# 可以匹配到条件{ "term": { "brand": "皇冠假日" } },{ "term": { "brand": "华美达" } }],"must_not": [	#不匹配的条件{ "range": { "price": {"lte": 500, "gte": 600} }}],"filter": [	#筛选条件{ "range": { "score": { "gte": 45 } } }]}	}
}

二、搜索结果处理

(一)排序

ES支持对搜索结果排序,默认根据(_score)来排序,可以排序的字段类型有:keyword、数值类型、地理坐标类型、日期类型等

1、结构:

# 普通类型排序
GET /test/_search
{"query": {"match_all": {}},"sort": [{"FIELD": {"order": "desc"		# 排序字段和排序方式ASC、DESC}}]
}# 地理坐标型排序
GET /test/_search
{"query": {"match_all": {}},"sort": [{"_geo_distance": {"FIELD": {  #精度维度"lat": 40,"lon": -70},"order": "asc","unit": "km"}}]
}

2、实现案例

排序需求: 按照用户评价降序,评价相同的按照价格升序。

GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"score": {  # 简化结构可以使用,"score": "desc""order": "desc"},"price": {"order": "asc"}}]
}

排序需求: 按照距离用户位置的距离进行升序。

GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"_geo_distance": {"location": {"lat": 40.58489,"lon": -70.59873},"order": "asc","unit": "km"}}]
}

(二)分页

修改分页参数

GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"price": "asc"}],"from": 100,	#	分页开始的位置,默认为0"size": 20,	#	期望获取的文档总数
}

深度分页问题

当我们将ES做成一个集群服务,那么我们需要选择前10的数据时,ES底层会如何去实现呢?

ES由于使用的是倒排索引,每一台ES都会分片数据。

1、每个数据分片上都排序并查询前1000条文档。

2、聚合所有节点的结果,在内存中重新排序选出前1000条文档。

3、从前1000挑中,选取from=990,size=10的文档

如果搜索页数过深,或者结果集过大,对内存和CPU的消耗越高,因此ES设置的结果集查询上限是10000条。

如何解决深度分页的问题?

  • seach after: 分页时需要排序,原理是从上一次的排序值开始,查询下一页数据(官方推荐)。
  • scroll: 原理是将排序数据形成缓存保存在内存(官方不推荐)。

(三)高亮

1、概念: 在搜索结果中搜索关键字突出显示。

2、原理

  • 将搜索结果中的关键字用标签标记出来
  • 在页面中给标签添加css样式

3、语法:

GET /indexName/_search
{"query": {"match": {"FIELD": "TEXT"}},"highlight": { 	#高亮字段"fields": {"FIELD": {"pre_tags": "<em>",  	#标签前缀"post_tags": "</em>", 	#标签后缀"require_field_match": "false"	#判断该字段是否与前面查询的字段匹配}}}
}

三、RestClient查询文档

(一)实现简单查询案例

//1、准备Request
SearchRequest request = new SearchRequest("hotel");
//2、组织DSL参数,QueryBuilders是ES的查询API库
request.source().query(QueryBuilders.matchAllQuery());
//3、发送请求,得到响应结果
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4、解析响应结果,搜索结果会放置在Hits集合中
SearchHits searchHits = response.getHits();
//5、查询总数
long total = searchHits.getTotalHits().value;
//6、查询的结果数组
SearchHit[] hits = searchHits.getHits();
for(SearchHit hit: hits) {//得到source,source就是查询出来的实体信息String json = hit.getSourceAsString();//序列化HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);
}

(二)match查询


//1、准备Request
SearchRequest request = new SearchRequest("hotel");
//2、组织DSL参数,QueryBuilders是ES的查询API库
//单字段查询
request.source().query(QueryBuilders.matchQuery("all","皇家"));
//多字段查询
//request.source().query(QueryBuilders.multiMatchQuery("皇家","name","buisiness"));
//3、发送请求,得到响应结果
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4、解析响应结果,搜索结果会放置在Hits集合中
SearchHits searchHits = response.getHits();
//5、查询总数
long total = searchHits.getTotalHits().value;
//6、查询的结果数组
SearchHit[] hits = searchHits.getHits();
for(SearchHit hit: hits) {//得到source,source就是查询出来的实体信息String json = hit.getSourceAsString();//序列化HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);
}

(三)精确查询

//词条查询
QueryBuilders.termQuery("city","杭州");
//范围查询
QueryBuilders.rangeQuery("price").gte(100).lte(150);

(四)复合查询

//创建布尔查询
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//添加must条件
boolQuery.must(QueryBuilders.termQuery("city","杭州"));
//添加filter条件
boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));

(五)排序、分页、高亮

1、排序与分页

// 查询
request.source().query(QueryBuilders.matchAllQuery());
// 分页配置
request.source().from(0).size(5);
// 价格排序
request.source().sort("price", SortOrder.ASC);

2、高亮

高亮查询请求

request.source().highlighter(new HighLightBuilder().field("name").requireFieldMatch(false));

处理高亮结果

// 获取source
HotelDoc hotelDoc = JSON.parseObject(hit.getSourceAsString(), HotelDoc.class);
// 处理高亮
Map<String, HighlightFields> highlightFields = hit.getHighlightFields();
if(!CollectionUtils.isEmpty(highlightFields)) {// 获取字段结果HighlightField highlightField = highlightFields.get("name");if (highlightField != null) {// 去除高亮结果数组的第一个String name = highlightField.getFragments()[0].string();hotelDoc.setName(name);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode 50. Pow(x, n)(x的n次方)

求x的n次方。 思路&#xff1a; 第一个想到的思路是x和它自己乘n次&#xff0c; 但是这样做会面临一些问题&#xff1a; 如果是简单的n很小的情况还好&#xff0c;但是可以看到n的取值横跨整个整数范围&#xff0c; 如果n非常大&#xff0c;一次一次乘x效率低是其一。 一般来…

探索网页原型设计:构建出色的用户体验

在当今数字化时代&#xff0c;用户对网页体验的要求日益提高。在网页设计过程中&#xff0c;扮演着至关重要的角色。通过网页原型设计&#xff0c;产品经理能够更好地展示和传达网页的整体布局、导航结构、元素位置和交互效果&#xff0c;从而使团队成员更清晰地了解设计意图&a…

mapboxGL中楼层与室内地图的结合展示

概述 质量不够&#xff0c;数量来凑&#xff0c;没错&#xff0c;本文就是来凑数的。前面的几篇文章实现了楼栋与楼层单体化的展示、室内地图的展示&#xff0c;本文结合前面的几篇文章&#xff0c;做一个综合的展示效果。 实现效果 实现 1. 数据处理 要实现上图所示的效果…

Excel透视表与python实现

目录 一、Excel透视表 1、源数据 2、数据总分析 3、数据top分析 二、python实现 1、第一张表演示 2、第二张表演示 一、Excel透视表 1、源数据 1&#xff09;四个类目&#xff0c;每类50条数据 2&#xff09;数据内容 2、数据总分析 1&#xff09;选择要分析的字段&…

leetcode做题笔记46

给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 思路一&#xff1a;回溯 void swap(int *nums,int index1,int index2) {int temp nums[index1];nums[index1] nums[index2];nums[index2] temp; }void prem(int* nu…

已经重新安装了MySQL,第一次应该如何登录root用户

如果已经重新安装了MySQL&#xff0c;第一次登录root用户需要按照以下步骤进行&#xff1a; 1. 打开命令行终端或控制台。 2. 通过一下命令启动MySQL服务器&#xff1a; sudo systemctl start mysql3. 登录MySQL服务器&#xff1a; sudo mysql -u root 如果服务器在本地主…

vue项目登录页面实现记住用户名和密码

vue项目登录页面实现记住用户名和密码 记录一下实现的逻辑&#xff0c;应该分两步来理解这个逻辑 首次登录&#xff0c;页面没有用户的登录信息&#xff0c;实现逻辑如下&#xff1a; 用户输入用户名和密码登录&#xff0c;用户信息为名为form的响应式对象&#xff0c;v-model…

Linux Day03

一、基础命令(在Linux Day02基础上补充) 1.10 find find 搜索路径 -name 文件名 按文件名字搜索 find 搜索路径 -cmin -n 搜索过去n分钟内修改的文件 find 搜索路径 -ctime -n搜索过去n分钟内修改的文件 1&#xff09;按文件名字 2&#xff09;按时间 1.11 grep 在文件中过…

linux+Jenkins+飞书机器人发送通知(带签名)

文章目录 如何使用在linux 上安装python 环境发送消息python脚本把脚本上传倒linux上 jenkins 上执行脚本 如何使用 自定义机器人使用指南飞书官网https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot 在linux 上安装python 环境 yum install python3 python…

yolov5检测到的框画到原图上

1.把检测到的框画到原图上 import warnings warnings.filterwarnings(ignore) warnings.simplefilter(ignore) import torch import cv2 import numpy as np import requests import torchvision.transforms as transformsfrom models.common

“深入解析Spring Boot:从入门到进阶“

标题&#xff1a;深入解析Spring Boot&#xff1a;从入门到进阶 摘要&#xff1a;本文将深入解析Spring Boot框架&#xff0c;从入门到进阶&#xff0c;帮助开发者更好地理解和应用Spring Boot。内容包括Spring Boot的基本概念、核心特性、常用组件和高级用法&#xff0c;并提…

如何在3ds max中创建可用于真人场景的巨型机器人:第 5 部分

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. After Effects 中的项目设置 步骤 1 打开“后效”。 打开后效果 步骤 2 我有真人版 我在After Effects中导入的素材。这是将 用作与机器人动画合成的背景素材。 实景镜头 步骤 3 有背景 选定的素材…

Mindar.JS——实现AR图像追踪插入图片或视频

Mindar.JS使用方式 注意&#xff1a;此篇文章需要启动https才可调用相机权限 图像追踪示例 需要用到两个js库 <script src"./js/aframe.min.js"></script><script src"./js/mindar-image-aframe.prod.js"></script>下面看一下标签…

原生js vue react通用的递归函数

&#x1f642;博主&#xff1a;锅盖哒 &#x1f642;文章核心&#xff1a;原生js vue react通用的递归函数 目录大纲 1.递归函数的由来 2.代码逻辑 1.递归函数的由来 递归函数的由来可以追溯到数学中的递归概念和数学归纳法。 在数学中&#xff0c;递归是指通过定义基本情况和…

vue+leaflet笔记之地图聚合

vueleaflet笔记之地图聚合 文章目录 vueleaflet笔记之地图聚合开发环境代码简介插件简介与安装使用简介 详细源码(Vue3) 本文介绍了Web端使用Leaflet开发库进行地图聚合查询的一种方法 (底图来源:中科星图)&#xff0c;结合Leaflet.markercluster插件能够快速的实现地图聚合查询…

计算机组成原理(2)- 浮点数的存储

1、浮点数的表示方法 假设有以下小数&#xff0c;它表示的十进制数是多少呢&#xff1f; 00000000 00000000 00000000 1010.10101*2^3 1*2^1 1*2^-1 1*2^-3 10.625 1010.1010可以用科学计数法来表示为1.0101010 * 2^3。关于科学计数法再举个例子0.10101用科学计数法表示…

Docker容器基本操作之启动-停止-重启

一、安装启动RabbitMQ容器 此处以rabbitmq容器为例 前提&#xff1a;需要安装配置好docker(设置镜像源、配置阿里云加速)、开启docker&#xff0c;停止(stop)或者禁用(disable)手动解压缩安装的rabbitmq,以防与docker中安装的rabbitmq冲突。 //查看docker状态 systemctl stat…

计算机视觉(四)神经网络与典型的机器学习步骤

文章目录 神经网络生物神经元人工神经元激活函数导数 人工神经网络“层”的通俗理解 前馈神经网络Delta学习规则前馈神经网络的目标函数梯度下降输出层权重改变量 误差方向传播算法误差传播迭代公式简单的BP算例随机梯度下降&#xff08;SGD&#xff09;Mini-batch Gradient De…

SRS开源代码框架,协程库state-threads的使用

本章内容解读SRS开源代码框架&#xff0c;无二次开发&#xff0c;以学习交流为目的。 SRS是国人开发的流媒体服务器&#xff0c;C语言开发&#xff0c;本章使用版本&#xff1a;https://github.com/ossrs/srs/tree/5.0release。 目录 SRS协程库ST的使用源码ST协程库测试SrsAut…

Go语言网络库net/http

Go语言网络库net/http Http 协议(Hyper Text Transfer Protocol&#xff0c;超文本传输协议)是一个简单的请求-响应协议&#xff0c;它通常运行在 TCP 之 上。超文本传输协议是互联网上应用最为广泛的一种网络传输协议&#xff0c;所有的WWW文件都必须遵守这个标准。 Http 协…