实用篇-ES-DSL查询文档

数据的存储不是目的,我们希望从海量的酒店数据中检索出需要的信息,这就是ES的搜索功能

官方文档: https://elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html#query-dsl。DSL是用来查询文档的

Elasticsearch提供了基于JSON的DSL来定义查询,简单说就是用json来描述查询条件,然后发送给es服务,最后es服务基于查询条件,把结果返回给我们

常见的查询类型包括如下:

1、查询所有: 查询出所有数据,一般在测试的时候使用

match_all

2、全文检索查询: 利用分词器对用户输入内容进行分词,然后去倒排索引库中匹配

match_query
multi_match_query

3、精确查询: 根据精确的词条值去查找数据,一般是查找keyword、数值、日期、boolean等类型的字段。这些字段是不需要分词的,但是依旧会建立倒排索引,把字段的整体内容作为一个词条,并存入倒排索引。在查找的时候,也就不需要分词,直接把搜索的内容去跟倒排索引匹配即可

ids,表示根据id,进行精确匹配range,表示根据数值范围,进行精确匹配term,表示根据数据的值,进行精确匹配

4、地理查询: 根据经纬度查询

geo_distance
geo_bounding_box

5、复合查询: 复合查询可将上述各种查询条件组合一起,合并查询条件

bool,利用逻辑运算把其它查询条件组合起来
function_score,用于控制相关度算分,算分会影响性能

一、DSL查询语法

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

存在一个问题,我们明明查询的是所有文档,查询结果也显示查询出所有的文档了,为什么上图右侧,鼠标往下拉,最多才只有10条文档数据呢

原因: 受默认的分页条件限制,后面学习的时候,会进行解决

二、全文检索查询

首先保证你已经做好了 '实用篇-ES-环境搭建' ,创建了名为hotel的索引库,导入了批量文档。然后开始下面的操作

全文检索查询,分为下面两种,会对用户输入内容进行分词之后,再进行匹配。也就是利用分词器对用户输入内容进行分词,然后去倒排索引库中匹配

match_query
multi_match_query

【第一种全文检索查询】

match查询(也就是match_query查询): 全文检索查询的一种,会对用户输入的内容进行分词,然后去倒排索引库检索

GET /索引库名/_search
{"query": {"match": {"字段名": "TEXT"}}
}

具体操作如下,为了让大家知道hotel索引库有哪些字段,我把当初建立gghotel索引库的类先放出来

package cn.itcast.hotel.constants;public class HotelConstants {public static final String MAPPING_TEMPLATE = "{\n" +"  \"mappings\": {\n" +"    \"properties\": {\n" +"      \"id\":{\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"      \"name\":{\n" +"        \"type\": \"text\",\n" +"        \"analyzer\": \"ik_max_word\",\n" +"        \"copy_to\": \"all\"\n" +"      },\n" +"      \"address\":{\n" +"        \"type\": \"keyword\",\n" +"        \"index\":false\n" +"      },\n" +"      \"price\":{\n" +"        \"type\": \"integer\"\n" +"      },\n" +"      \"score\":{\n" +"        \"type\": \"integer\"\n" +"      },\n" +"      \"brand\":{\n" +"        \"type\": \"keyword\",\n" +"        \"copy_to\": \"all\"\n" +"      },\n" +"       \"city\":{\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"       \"starName\":{\n" +"        \"type\": \"keyword\"\n" +"      },\n" +"       \"business\":{\n" +"        \"type\": \"keyword\",\n" +"        \"copy_to\": \"all\"\n" +"      },\n" +"       \"location\":{\n" +"        \"type\": \"geo_point\"\n" +"      },\n" +"      \"pic\":{\n" +"        \"type\":\"keyword\",\n" +"        \"index\": false\n" +"      },\n" +"      \"all\":{\n" +"        \"type\": \"text\",\n" +"        \"analyzer\": \"ik_max_word\"\n" +"      }\n" +"    }\n" +"  }\n" +"}";
}

注意: 我要解释一下,上面有个字段叫all,那个字段是当时自定义的,不清楚的话可回去看 '实用篇-ES-RestClient操作' 的 'hotel数据结构分析'。

all的作用如下图,相当于一个大的字段,里面存放了几个小字段,优点是我们可以在这个大的字段里面搜索到多个小字段的信息

然后,我们就正式开始全文检索查询,输入如下。注意all换成其它字段也没事,例如换成name字段。正常来说,我们检索name字段,就只在name字段检索匹配的分词文档,但是在all字段里面检索时,也会检索到name、brand、business字段,原因如上面那个图的copy_to属性

GET /hotel/_search
{"query": {"match": {"all": "外滩"}}
}//或者如下
# 第一种全文检索查询 match。查询name字段中包含'酒店'的文档
GET /hotel/_search
{"query": {"match": {"name": "酒店"}}
}

【第二种全文检索查询】

multi_match(也就是multi_match_query查询): 与match查询类似,只不过允许同时查询多个字段

GET /索引库名/_search
{"query": {"multi_match": {"query": "TEXT","字段名": ["FIELD1", " FIELD12"]}}
}
# 第二种全文检索查询 multi_match。查询business、brand、name字段中包含'如家'的文档,满足一个字段即可
GET /hotel/_search
{"query": {"multi_match": {"query": "如家","fields":["business","brand","name"]}}
}

三、精确查询

term: 根据词条的精确值查询,强调精确匹配

range: 根据值的范围查询,例如金额、时间

【第一种精确查询 term】

具体操作如下

查询city为杭州

GET /hotel/_search
{
"query":{"term":{"city":{"value":"杭州"}}}
}

【第二种精确查询 range】

GET /hotel/_search
{"query": {"range": {"price": {"gte": 10,"lte": 20}}}
}

四、地理查询

根据经纬度查询。常见的使用场景包括: 查询附近酒店、附近出租车、搜索附近的人。使用方式有很多种,介绍如下,这种最常用

geo_distance: 查询到指定中心点,以该点为圆心,distance为半径的圆,符合要求的所有文档

GET /索引库名/_search
{"query": {"geo_distance": {"distance": "15km","字段名": "31.21,121.5"}}
}

具体操作如下

输入如下DSL语句

GET /hotel/_search
{"query": {"geo_distance": {"distance": "15km","location": "31.21,121.5"}}
}

五、相关性算分

上面学的全文检索查询、精确查询、地理查询,这三种查询在es当中都称为简单查询,下面我们将学习复合查询。复合查询可以其它简单查询组合起来,实现更复杂的搜索逻辑,其中就有 '算分函数查询' 如下

首先保证你已经做好了 '实用篇-ES-环境搭建' ,创建了名为hotel的索引库,导入了批量文档。然后开始下面的操作

算分函数查询(function score): 可以控制文档相关性算分、控制文档排名。例如搜索'外滩' 和 '如家' 词条时,某个文档要是都能匹配这两个词条,那么在所有被搜索出来的文档当中,这个文档的位置就最靠前,简单说就是越匹配就排名越靠前

六、函数算分查询

上面只是简单演了相关性打分中的函数算分查询,文档与搜索关键字的相关度越高,打分就越高,排名就越靠前。不过,有的时候,我们希望人为地去控制控制文档的排名,例如某些文档我们就希望排名靠前一点,算分高一点,此时就需要使用函数算分查询,下面就来学习 '函数算分查询'

首先保证你已经做好了 '实用篇-ES-环境搭建' ,创建了名为gghotel的索引库,导入了批量文档。然后开始下面的操作

使用 ’函数算分查询(function score query)’,可以在原始的相关性算分的基础上加以修改,得到一个想要的算分,从而去影响文档的排名,语法如下

GET /索引库名/_search
{"query": {"function_score": {"query": { "match": {"字段": "词条"} },"functions": [{"filter": {"term": {"指定字段": "值"}},"算分函数": 函数结果}],"boost_mode": "加权模式"}}
}

function score需要考虑的三要素

1. 哪些文档需要算分加权

2. 算分函数是什么

3. 加权模式是什么

下面我们实现一个案例:给如家这个品牌的酒店排名靠前一些

考虑三要素

1. 哪些文档需要算分加权     brand为如家的酒店

2. 算分函数是什么               weigh

3. 加权模式是什么                相加/相乘都可

输入如下DSL语句,表示在 '如家' 这个品牌中,字段为'北京'的酒店排名靠前一些

GET /hotel/_search
{"query": {"function_score": {"query": {"match": {"brand": "如家"}},"functions": [{"filter": {"term": {"city": "北京"}},"weight": 2}],"boost_mode": "sum"}}
}

七、布尔查询

这是第二种复合查询

布尔查询不会去修改算分,而是把多个查询语句组合成一起,形成新查询,这些被组合的查询语句,被称为子查询。子查询的组合方式有如下四种

1、must:必须匹配每个子查询,类似"与"

2、should:选择性匹配子查询,类似"或"

3、must_not:必须不匹配,不参与算分,类似"非"

4、filter:必须匹配,不参与算分

首先保证你已经做好了 '实用篇-ES-环境搭建' ,创建了名为gghotel的索引库,导入了批量文档。然后开始下面的操作

输入如下DSL语句,表示搜索名字包含'如家',价格不高于400,在坐标31.21,121.5周围10km范围内的文档

GET /hotel/_search
{"query": {"bool": {"must": [{"match": {"name": "如家"}}],"must_not": [{"range": {"price": {"gt": 400}}}],"filter": [{"geo_distance": {"distance": "10km","xxlocation": {"lat": 31.21,"lon": 121.5}}}]}}
}

八、搜索结果处理

lasticsearch(称为es)支持对搜索的结果,进行排序,默认是根据 '相关度' 算分,也就是score值,根据score值进行排序。

可以排序的字段类型有: keyword类型、数值类型、地理坐标类型、日期类型

首先保证你已经做好了 '实用篇-ES-环境搭建' ,创建了名为gghotel的索引库,导入了批量文档。然后开始下面的操作

1. 排序

输入如下DSL语句,表示对所有的文档,根据评分(score)进行降序排序,如果评分相同就根据价格(price)升序排序

GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"score": {"order": "desc"},"price": {"order": "asc"}}]
}

2. 分页

elasticsearch(称为es)默认情况下只返回前10 条数据。而如果要查询更多数据就需要修改分页参数,分页参数包括from和size,语法如下

GET /索引库名/_search
{"query": {"要查询的字段": {}},"from": 要查第几页, // 分页开始的位置,默认为0"size": 每页显示多少条文档, // 期望获取的文档总数"sort": [ //表示排序{"price": "排序方式"}]
}

输入如下DSL语句,表示对所有的文档,根据价格(price)进行升序排序,每次分页显示20条数据,看的是第六页

size默认是10,表示一页显示多少条文档。from默认是0,表示你要看的是第一页

GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"price": {"order": "asc"}}],"from": 5,"size": 20
}

3. 搜索结果处理-高亮

高亮: 就是在搜索结果中把搜索关键字突出显示。高亮显示的原理如下

1、将搜索结果中的关键字用标签标记出来

2、在页面中给标签添加css样式

首先保证你已经做好了 '实用篇-ES-环境搭建' ,创建了名为gghotel的索引库,导入了批量文档。然后开始下面的操作

语法

GET /索引库名/_search
{"query": {"match": { //match表示带关键字的查询"字段": "TEXT"}},"highlight": {"fields": {"字段名": {"require_field_match": "false",//默认是true,表示 '字段' 要和 '字段名' 要一致。如果我们写的是不一致的话,就需要修改为false"pre_tags": "<em>",  // 用来标记高亮字段的前置标签,es会帮我们把标签加在关键字上。默认是<em>"post_tags": "</em>" // 用来标记高亮字段的后置标签,es会帮我们把标签加在关键字上。默认是</em>}}}
}

 总结

GET /索引库名/_search
{"query": {"match": {"字段名": "如家"}},"from": 0, // 分页开始的位置"size": 20, // 期望获取的文档总数"sort": [ {  "price": "asc" }, // 普通排序{"_geo_distance" : { // 距离排序"location" : "31.040699,121.618075", "order" : "asc","unit" : "km"}}],"highlight": {"fields": { // 高亮字段"字段名": {"pre_tags": "<em>",  // 用来标记高亮字段的前置标签"post_tags": "</em>" // 用来标记高亮字段的后置标签}}}
}

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

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

相关文章

大师学SwiftUI第18章Part1 - 图片选择器和相机

如今&#xff0c;个人设备主要用于处理图片、视频和声音&#xff0c;苹果的设备也不例外。SwiftUI可以通过​​Image​​视图显示图片&#xff0c;但需要其它框架的支持来处理图片、在屏幕上展示视频或是播放声音。本章中我们将展示Apple所提供的这类工具。 图片选择器 Swift…

基于libcurl+libopenssl开源库编译出curl下载工具及代码集成curl功能

准备素材&#xff1a; 1. openssl的版本&#xff1a; openssl-1.1.1w.tar.gz 2.curl的版本&#xff1a;curl-8.4.0.tar.gz 目标&#xff1a; 1.编译出openssl库&#xff1b; 2.编译出curl可执行文件及库&#xff1b; 步骤一&#xff1a;先解压压缩包 tar -zxvf openssl-1…

魔术《4 Kings 折纸》的三重境界(四)——魔术效果的突破

‍ ‍早点关注我&#xff0c;精彩不错过&#xff01; 在前三篇文章里&#xff0c;我们解释清楚了分别基于奇偶性&#xff0c;集合和群论来解释《4 Kings 折纸》这个魔术的过程&#xff0c;详情请戳&#xff1a; 魔术《4 Kings 折纸》的三重境界&#xff08;三&#xff09;——群…

量化交易:传统小市值策略 VS AI市值策略

在BigQuant平台上可以快速开发股票传统策略和股票AI策略&#xff0c;今天拿市值因子来练手&#xff0c;看看两个策略在2015-01-01到2016-12-31这两年时间各自的收益风险情形。 市值因子是国内股票市场能够带来超额收益的alpha因子&#xff0c;已经被验证为长期有效的因子&…

ajax,axios,fetch

文章目录 ajax工作原理ajax发请求四个步骤创建xmlhttprequest对象设置请求方式设置回调函数发送请求 自封装ajax axiosaxios 特性如何用配置拦截器fetch 三者区别 ajax 工作原理 Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎)&#xff0c;使用户操作与服务…

调试/抓包工具

一、Fiddler【推荐window使用】 介绍&#xff1a;个人认为是 Windows 平台最好用的抓包工具&#xff1b; 下载&#xff1a;Fiddler | Web Debugging Proxy and Troubleshooting Solutions 使用方式&#xff1a;这一篇文章写的很全&#xff0c;认真看完就够用了 Fiddler 抓包工…

QtCreator开发环境的安装和配置

QtCreator开发环境的安装和配置 介绍下载与安装环境介绍示例新建工程示例程序 帮助模式Qt Designer(设计师)Qt Linguist(预言家)结论 介绍 Qt Creator是一个跨平台、完整的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门用于Qt开发。它包含了完整的编辑器、调试器和…

H5ke11..--2其他界面也要提取我的locatStarage

获取浏览器里面的本地缓存 localStorage就是我们的浏览器缓存在哪都可以用,调用我们的locatStarage就行 下面代码是获取打印到我们的页面上 修改在我们另一个界面得到 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&quo…

酷柚易汛ERP - 权限设置操作指南

1、产品介绍 对系统的同事管理、角色管理、数据授权进行设置 1.1 同事管理 对当前系统添加同事账号&#xff0c;超级管理员不允许删除 1.2 角色管理 对当前系统添加角色&#xff0c;系统中可以设置多种角色&#xff0c;不同角色设置不同权限&#xff0c;方便添加同事时进行…

Linux嵌入式I2C协议笔记

硬件: 1.I2C结构 在一个SOC中有一个或者多个I2C控制器,一个I2C控制器可以连接一个或多个I2C设备。 I2C总线需要两条线,时钟线SCL和数据线SDA 2.I2C传输数据格式 开始信号(S):SCL为高电平时,SDA山高电平向低电平跳变,开始传送数据。结束信号(P):SCL为高电平时,SDA…

CI/CD -gitlab

目录 一、常用命令 二、部署 一、常用命令 官网&#xff1a;https://about.gitlab.com/install/ gitlab-ctl start # 启动所有 gitlab 组件 gitlab-ctl stop # 停止所有 gitlab 组件 gitlab-ctl restart # 重启所有 gitlab 组件 gitlab-ctl statu…

Maven依赖管理项目构建工具(保姆级教学---下篇)

对于Maven依赖管理项目构建工具的介绍&#xff0c;我们将其分为上篇和下篇。如果您对文章感兴趣&#xff0c;您可以在此链接中找到上篇详细内容&#xff1a; Maven依赖管理项目构建工具&#xff08;保姆级教学上篇&#xff09;-CSDN博客 一、Maven依赖传递和依赖冲突 1. …