微服务学习|DSL查询语法、搜索结果处理、RestClient查询文档、黑马旅游案例

DSL查询语法

DSLQuery的分类

Elasticsearch提供了基于JSON的DSL (Domain Specific Language) 来定义查询。常见的查询类型包括:

查询所有:查询出所有数据,一般测试用。例如:match_all
全文检索 (full text)查询: 利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:

match _query
multi_match_query
精确查询: 根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如
ids
range
term
地理 (geo)查询: 根据经纬度查询。例如:
geo_distance
geo_bounding_box
复合 (compound)查询: 复合查询可以将上述各种查询条件组合起来,合并查询条件。例如.
bool
function_score

DSLQuery基本语法

查询的基本语法如下

去查询酒店所有信息

全文检索查询

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

match查询

match查询:全文检索查询的一种,会对用户输入内容分词,然后去倒排索引库检索,语法

all中我们之前加入了有brand、business、name这些字段,“外滩如家”会在这几个字段中进行匹配,选出含有本词条的酒店信息

multi_match查询

multi_match:与match查询类似,只不过允许同时查询多个字段,语法

使用multi_match对词条“外滩如家”在brand、business、name这三个字段中去匹配查询,故此时和上面的match查询对all字段进行匹配查询效果一样。

match和multi_match的区别是什么?

match: 根据一个字段查询
mult_match: 根据多个字段查询,参与查询字段越多,查询性能越差

精确查询

精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有

term:根据词条精确值查询

range:根据值的范围查询

精确查询一般是根据id、数值、keyword类型、或布尔字段来查询。语法如下

term查询

根据词条精确值查询

对城市为“上海”的酒店进行精确查询,查出所有的所在城市都是上海的的酒店信息

将term查询中的精确查询内容的城市值换成“杭州上海”,因为所有的酒店城市没有是“杭州上海”的,所以查询结果为空

range查询

根据值的范围查询

根据酒店的价格price进行range查询,查出所有价格price在区间100-300元之间的酒店信息。

地理查询

根据经纬度查询。常见的使用场景包括

携程:搜索我附近的酒店

滴滴:搜索我附近的出租车

微信:搜索我附近的人

根据经纬度查询。例如

geo_bounding_box查询

geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档

geo_distance查询

geo_distance:查询到指定中心点小于某个距离值的所有文栏

查出在31.21,123.5这个点15km以内的所有酒店信息

复合查询

复合(compound)查询: 复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑,例如

fuction_score查询

fuction_score: 算分函数查询,可以控制文档相关性算分,控制文档排名。例如百度竞价

相关性算分

当我们利用match查询时,文档结果会根据与搜索词条的关联度打分( score),返回结果时按照分值降序排列。例如,我们搜索“虹桥如家",结果如下

fuction_score查询,可以修改文档的相关性算分 (query score),根据新得到的算分排序。

案例:给“如家”这个品牌的酒店排名靠前一些

把这个问题翻译一下,function score需要的三要素:

1.哪些文档需要算分加权? 品牌为如家的酒店
2.算分函数是什么? weight就可以
3.加权模式是什么? 求和

先普通的全文检索查询,“外滩”在brand、business、name这些字段中匹配,查询出符合要求的酒店信息

我们使得品牌为“如家”的酒店的最后得分,再乘以weight,可以看到刚才的那个酒店因为名字为”如家“,所以得分变成了38.828926,变成了以前的10倍

再定义权重的方式我们再查询,方式定义为sum,也就是其本来得分加上weight(10),故那个酒店的最后得分变成了13.882893,比最早的得分增加了10

复合查询 Boolean Query

布尔查询是一个或多个查询子句的组合。子查询的组合方式有
must: 必须匹配每个子查询,类似“与”
should:选择性匹配子查询,类似“或
must not:必须不匹配,不参与算分,类似“非'
filter: 必须匹配,不参与算分

案例:利用bool查询实现功能

需求:搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店

搜索结果处理

排序

elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有: keyword类型、数值类型、地理坐标类型、日期类型等

案例:对酒店数据按照用户评价降序排序,评价相同的按照价格升序排序

评价是score字段,价格是price字段,按照顺序添加两个排序规则即可

写出DSL

案例:实现对酒店数据按照到你的位置坐标的距离升序排序

写出DSL,看到返回的酒店信息里,每条增加了一个sort字段,4.8541199685347785意思就是距离你的位置有4.85km远,查到的酒店顺序是按照这个值升序排列的,越近的排的位置越靠前。

分页

elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。elasticsearch中通过修改from、size参数来控制要返回的分页结果

深度分页问题

ES是分布式的,所以会面临深度分页问题。例如按price排序后,获取from = 990,size =10的数据

1.首先在每个数据分片上都排序并查询前1000条文档

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

3.最后从这1000条中,选取从990开始的10条文档

如果搜索页数过深,或者结果集 (rom+size)越大,对内存和CPU的消耗也越高。因此ES设定结果集查询的上限是10000

深度分页解决方案

针对深度分页,ES提供了两种解决方案:
search after: 分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式

scroll:原理将排序数据形成快照,保存在内存。官方已经不推荐使用

高亮

高亮:就是在搜索结果中把搜索关键字突出显示。
原理是这样的:
将搜索结果中的关键字用标签标记出来
在页面中给标签添加css样式
语法:

编写DSL查询语句

搜索结果处理整体语法

RestClient查询文档

快速入门

我们通过match all来演示下基本的API,先看请求DSL的组织:

编写一个测试类,先将客户端进行初始化

编写match all查询的测试方法

查询结果

我们通过match_all来演示下基本的API,再看结果的解析

在刚才编写的测试方法里增加对结果的解析

查看结果,结果被解析成了一个个对应的hotelDoc对象

全文检索查询

全文检索的match和multi_match查询与match_all的API基本一致。差别是查询条件,也就是query的部分同样是利用QueryBuilders提供的方法

编写match查询的测试方法

可以发现,对与结果的解析这部分的代码每个查询都需要用到,故我们用ctrl+alt+m将这一块的代码抽取成一个单独的方法

抽取出的方法如下,在解析响应结果时,可直接使用

刚才的match查询的测试方法简化成如下所示

精确查询

精确查询常见的有term查询和range查询,同样利用QueryBuilders实现

复合查询-boolean query

精确查询常见的有term查询和range查询,同样利用QueryBuilders实现

编写boolean query查询测试方法

查询出所有city=杭州,price小于250的酒店信息

要构建查询条件,只要记住一个类: QueryBuilders

排序和分页

搜索结果的排序和分页是与query同级的参数,对应的API如下

编写排序和分页查询的测试方法

查询出价格按照升序排列,第一页且一页有5条的酒店信息。

高亮

高亮DSL构建

高亮API包括请求DSL构建和结果解析两部分。我们先看请求的DSL构建

编写高亮查询的测试方法

高亮结果解析

高亮的结果处理相对比较麻烦

在解析结果后面添加对高亮结果的处理

可以看到,返回的结果中name=如家的已经带上了高亮标签,前端接收到后对带有该标签的结果进行高亮显示即可

所有搜索DSL的构建,记住一个API:
SearchRequest的source()方法
高亮结果解析是参考JSON结果,逐层解析

黑马旅游案例

案例1: 实现黑马旅游的酒店搜索功能,完成关键字搜索和分页

我们课前提供的hotel-demo项目中,自带了前端页面,启动后可以看到

先实现其中的关键字搜索功能,实现步骤如下
1.定义实体类,接收前端请求
2.定义controller接口,接收页面请求,调用IHotelService的search方法

3.定义IHotelService中的search方法,利用match查询实现根据关键字搜索酒店信息

步骤1:定义类,接收前端请求参数

格式如下:

步骤2: 定义controller接口,接收前端请求

定义一个HotelController,声明查询接口,满足下列要求:
请求方式:Post
请求路径: /hotel/list
请求参数:对象,类型为RequestParam
返回值:PageResult,包含两个属性 Long total: 总条数 List<HotelDoc> hotels: 酒店数据

编写返回值PageResult类

编写Controller

服务层生成该业务方法

在这个项目的主启动类中初始化客户端

编写具体的业务方法

在返回的结果类中添加一个有参构造器

抽取出来的解析结果那个方法修改一些内容

以下是该查询的完整业务方法

运行后,发现方法成功运行

案例2:添加品牌、城市、星级、价格等过滤功能

需求效果如图

步骤:
1.修改RequestParams类,添加brand、city、starName、minPrice、maxPrice等参数

2.修改search方法的实现,在关键字搜索时,如果brand等参数存在,对其做过滤

步骤一: 拓展IUserService的search方法的参数列表

修改RequestParams类,接收所有参数

步骤二: 修改search方法,在match查询基础上添加过滤条件

过滤条件包括:
city精确匹配
brand精确匹配
starName精确匹配
price范围过滤
注意事项:
多个条件之间是AND关系,组合多条件用BooleanQuery
参数存在才需要过滤,做好非空判断

编写该业务方法

将构建BooleanQuery的内容抽取出来成为一个单独的方法

运行方法,业务成功运行

案例3: 我附近的酒店

前端页面点击定位后,会将你所在的位置发送到后台

我们要根据这个坐标,将酒店结果按照到这个点的距离升序排序

实现思路如下:

修改RequestParams参数,接收location字段

修改search方法业务逻辑,如果location有值,添加根据geo distance排序的功能

距离排序

距离排序与普通字段排序有所差异,API如下

将接收类扩展接收location字段

扩写之前的业务方法

sort中显示的是该酒店对自己位置的距离

在返回的结果类中扩展这个距离属性

在解析结果的方法中扩展解析sort距离值的内容,将该距离内容赋值给结果类

运行起来,业务成功实现

案例4: 让指定的酒店在搜索结果中排名置顶

我们给需要置顶的酒店文档添加一个标记。然后利用function_score给带有标记的文档增加权重

实现步骤分析:

1.给HotelDoc类添加isAD字段,Boolean类型

2.挑选几个你喜欢的酒店,给它的文档数据添加isAD字段,值为true

3.修改search方法,添加function score功能给isAD值为true的酒店增加权重

给结果类中填加isAD字段

挑选几个你喜欢的酒店,给它的文档数据添加isAD字段,值为true,就是模拟这几个酒店买广告了

组合查询-function score

Function score查询可以控制文档的相关性算分,使用方式如下

在业务方法中扩展该业务

启动方法,业务成功运行

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

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

相关文章

在QTableView中使用各种自定义委托

QT的MVC&#xff08;View/Delegate&#xff09;模型十分强大&#xff0c;可以利用各种控件来对表格的输入进行限制&#xff0c;不过我以前一直没有过&#xff0c;这几天研究了一下&#xff0c;写个小例子&#xff0c;希望大家喜欢。 如果看不懂这个例子&#xff0c;请先看QT的自…

带删除的并查集

Almost Union-Find 支持三种操作 合并 x x x和 y y y所在的集合把 x x x移到 y y y所在的集合求 x x x所在的集合的元素个数和元素之和 操作1和3是基本的并查集的操作. 关键在于操作 2 2 2: 若使用朴素的并查集&#xff0c;把节点 1 1 1合并到 3 3 3所在的集合&#xff0c;会…

List系列集合

List系列集合特点&#xff1a;有序&#xff0c;可重复&#xff0c;有索引 ArrayList&#xff1a;有序&#xff0c;可重复&#xff0c;有索引 LinkedList&#xff1a;有序&#xff0c;可重复&#xff0c;有索引 &#xff08;底层实现不同&#xff01;适合的场景不同&#xff01;…

TZOJ 1402 Bitset

答案&#xff1a; #include <stdio.h> int main() {int n 0, j 0; while (scanf("%d", &n) ! EOF && (n>0 && n<1000)) //多组输入{int arr[32], i 0;while (n > 0) {arr[i] n % 2; //除2取余法n / 2;}for (j i -…

接口自动化测试思路和实战之模块化测试脚本框架

模块化测试脚本框架 需要创建独立的可描述的模块、程序片断以及待测试应用程序的脚本。这些小脚本进行组合&#xff0c;就能组成用来独立运行特定的测试的测试用例脚本。 场景一: 开发把 access_token接口地址由/cgi-bin/token 改为/cgi-bin/get_token或者修改参数等 》开发把…

Zigbee—基于Z-STACK组网

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;チノカテ—ヨルシカ 0:46━━━━━━️&#x1f49f;──────── 4:08 &#x1f504; ◀️ ⏸ ▶️ ☰ &a…

Vue语音播报,不用安装任何包和插件,直接调用。

Vue语音播报功能可以通过使用浏览器提供的Web Speech API来实现。这个API允许你的应用程序通过浏览器朗读文本&#xff0c;不用安装任何包和插件&#xff0c;直接调用。以下是一个简单的介绍&#xff0c;演示如何在Vue中使用语音提示功能&#xff1a; 一、JS版本 <template…

基于springboot+vue的秒杀商城(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

IntelliJ IDEA安装使用教程

IntelliJ IDEA是一个流行的Java 集成开发环境&#xff08;IDE&#xff09;&#xff0c;由JetBrains公司开发。它是一款全功能的IDE&#xff0c;支持多种编程语言&#xff0c;如Java、Kotlin、Groovy、Scala、Python、JavaScript、HTML、CSS等等。IntelliJ IDEA 提供了高效的代码…

SAP_ABAP_编程基础_列表_自定义列表 / 多页列表 / 列表页面设置

SAP ABAP 顾问&#xff08;开发工程师&#xff09;能力模型_Terry谈企业数字化的博客-CSDN博客文章浏览阅读494次。目标&#xff1a;基于对SAP abap 顾问能力模型的梳理&#xff0c;给一年左右经验的abaper 快速成长为三年经验提供超级燃料&#xff01;https://blog.csdn.net/j…

软件测试-测试用例案例及思维导图展示

自动售货机的测试用例 一个杯子的测试用例 一支笔的测试用例 朋友圈点赞的测试用例 功能测试 1点赞后是否显示结果 2.点赞后是否可以取消; 3.点赞取消后是否可以重复点赞; 4.共同好友点赞后&#xff0c;是否有消息提醒; 5.非共同好友点赞后&#xff0c;是否有消息提醒; 6.点击…

IDEA:官方汉化包

CtrlAlts进入setting找到Plugins&#xff0c;直接在如下的搜索框中输入chinese回车 之后就是这样的啦~

应用互斥:一次只能开启一个实例

在真实应用中&#xff0c;经常需要一个可执行文件&#xff0c;只能产生一个进程&#xff0c;如果多次执行可能导致bug。 最典型的应用是微信&#xff0c;它虽然不构成多个进程存在会报异常的问题。但是它是一个很好的例子。无论怎么操作都只能在一个环境下只有一个微信进程。 …

【矩阵论】Chapter 2—内积空间知识点总结复习

文章目录 内积空间1 内积空间2 标准正交向量集3 Gram-Schmidt正交化方法4 正交子空间5 最小二乘问题6 正交矩阵和酉矩阵 内积空间 1 内积空间 内积空间定义 设 V V V是在数域 F F F上的向量空间&#xff0c;则 V V V到 F F F的一个代数运算记为 ( α , β ) (\alpha,\beta) (α…

【GraphQL】PostGraphile简介

Introduction to PostGraphile 什么是PostGraphile&#xff1f; 如果您熟悉Spring Data JPA&#xff0c;那么理解PostGraphile将非常容易。但没关系。让我们来看看。PostgreSQL数据库是一个非常流行的高性能应用数据库。ProstGraphile与PostgreSQL数据库和GraphQL配合使用。 …

YOLOv5全网独家首发改进:SENetv2,Squeeze-Excitation模块融合Dense Layer,效果秒杀SENet

💡💡💡本文自研创新改进:SENet v2,针对SENet主要优化点,提出新颖的多分支Dense Layer,并与Squeeze-Excitation网络模块高效融合,融合增强了网络捕获通道模式和全局知识的能力 推荐指数:五星 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/catego…

安防监控系统的工作原理是什么?具体包含哪些组成部分?

关于安防监控系统&#xff0c;大家熟知的就是监控系统平台&#xff0c;其实不然&#xff0c;智能视频安防监控系统涵盖的内容非常多&#xff0c;今天小编就和大家一起来探讨一下。 安防监控视频系统主要分为以下7大类&#xff1a; 1、 摄像头采集图像 安防监控系统通常使用摄…

单片机实验(三)

前言 实验一&#xff1a;利用定时器T1的中断控制P1.7引脚输出音频信号&#xff0c;启动蜂鸣器发出一段熟悉的与众不同的具有10个音节的音乐音频。 实验二&#xff1a;使用定时器/计数器来实现一个LCD显示年、月、日、星期 、时、分、秒的电子表&#xff0c;要求时和分可以方便…

全系降3万,一把干到底,极越「智取」特斯拉

作者|德新 编辑|王博 11月30日&#xff0c;极越01官宣全系降价3万。 这意味着21.99万起步的极越01 Max&#xff0c;成为这个市场上入门门槛最低的带有城市智能驾驶辅助功能的车型。 要知道这是一台比Model Y大了一圈&#xff0c;全系配置了高阶智驾硬件&#xff0c;全系配高…

【Openstack Train安装】十二、Cinder安装

Cinder在块存储资源和计算服务&#xff08;Nova&#xff09;之间提供了一个抽象层。通过Cinder API&#xff0c;块存储可以被管理&#xff08;创建、销毁和分配等&#xff09;&#xff0c;而不需要知道提供存储的底层资源。 本文介绍Cinder安装步骤&#xff0c;Cinder需在控制节…