《ElasticStack从入门到实践》学习笔记4

2024-03-19 22:30

本文主要是介绍《ElasticStack从入门到实践》学习笔记4,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

四、ElasticSearch的Search API

    0、在ES中,为了实现对存储的数据进行查询分析,使用endpoint:_search

        可以实现对索引的不同查询,如:

        A、实现对所有索引的泛查询:GET /_search

        B、实现对一个索引的单独查询:GET /my_index/_search

        C、实现对多个索引的指定查询:GET /my_index1,my_index2/_search

        D、实现对符合指定要求的索引进行查询:GET /my_*/_search

        在进行查询的时候,主要有两种方式:

        A)URI Search。

            特点:操作简单,直接通过命令行方便测试,但仅包含部分查询语法;

            举例:

#URI Search方式进行查询
GET /my_index/_search?q=username:alfred

        B)Request Body Search。

            特点:ES提供的完备查询语法,使用Query DSL(Domain Specific Language)进行查询。

            举例:

Request Body Search方式进行查询
GET /my_index/_search
{"query":{"match":{"username":"alfred"}}
}

    1、URI Search:

        1)通过url query参数实现搜索,常用参数有:

            A、q                            指定查询的语句,使用query string syntax语法

            B、df                           q中不指定字段时默认查询的字段    ===>   在不指定的时候默认查询所有字段

            C、sort                       排序

            D、timeout                 指定超时时间,默认不超时   

            E、from,size            用于分页

        举例:

#使用url query查询示例:
GET my_index/_search?q=alfred&df=username&sort=age:asc&from=4&size=10&timeout=1s

        解释:

        查询索引my_indexusername字段中包含alfred的文档,结果按age字段升序排列,返回第5——14个文档,若超过1s未结束,则以超时结束。

        2)query string syntax语法

            前置内容:term————单词,phrase————词语。

            A、单词与词语语法:

                单词:alfred way    等价于    alfred OR way

                词语:"alfred way"    语句查询,要求先后顺序

                泛查询:不指定字段,会在所有字段中去匹配其单词

                指定字段查询:指定字段,在指定字段中匹配单词

            B、Group分组设定,使用括号指定匹配的规则,举例:

#分组设定,使用括号进行分组
GET my_index/_search?q=username:(alfred OR way)AND lee

        3)search api

            A、泛查询:

#泛查询
GET my_index/_search?q=alfred
{"profile":true    #使用profile参数,可以明确地看到ES如何执行的查询条件
}

            B、指定字段查询:

                    a、查询字段username中包含alfred的文档:

#查询字段username中包含alfred的文档
GET my_index/_search?q=username:alfred

                    b、查询字段username中包含alfred或way的文档

#查询字段username中包含alfred或way的文档
GET my_index/_search?q=username:alfred way

                    c、查询字段username为"alfred way"的文档

#查询字段username为"alfred way"的文档
GET my_index/_search?q=username:"alfred way"

                    d、分组后,查询字段username中包含alfred和包含way的文档

#分组后,查询字段username中包含alfred,包含way的文档
GET my_index/_search?q=username:(alfred way)

                    这个和b的结果一样,但是区别在于使用分组之后,不进行泛查询。

        4)布尔操作符

            A、AND(&&)、OR(||)、NOT(!),举例:

#查询索引my_index中username包含alfred但是不包含way的文档
GET my_index/_search?q=username:(alfred NOT way)

            B、+对应must,-对应must_not,举例:

#查询索引my_index中一定包含lee,一定不含alfred,可能有way的文档
GET my_index/_search?q=username:(way +lee -alfred)
#或写成
GET my_index/_search?q=username:((lee && !alfred) || (way && lee && !alfred))

            但是要注意一点:

            在url中,+(加号)会被解析成空格,所以要使用encode后的结果,即:%2B,所以正确的查询语句应该为:

#查询索引my_index中一定包含lee,一定不包含alfred,可能包含way的文档
GET my_index/_search?q=username:(way %2Blee -alfred)

        5)范围查询(支持数值和日期)

            A、区间写法:闭区间使用[ ],开区间使用{ }

                a、age:[1 TO 10]                                1 <= age <= 10

                b、age:[1 TO 10}                                1 <= age < 10

                c、age:[1 TO ]                                     age >= 1

                d、age:[* TO 10]                                age <= 10

            B、算数符号写法:

                a、age:>= 1                                        

                b、age:(>=1 && <= 10) / age:(+ >= 1 + <= 10)

                举例:

#查询索引my_index中username字段包含alfred或年龄大于20的文档
GET my_index/_search?q=username:alfred age>20#查询索引my_index中username字段包含alfred且年龄大于20的文档
GET my_index/_search?q=username:alfred AND age>20

            C、还可以对日期进行范围查询,注意:年/月是从1月1号/1号开始算的:

#查询索引my_index中birth字段在1985和1990之间的文档
GET my_index/_search?q=birth:(>1985 AND < 1990)

        6)通配符查询

            ?代表一个字符,*代表0个或多个字符,如:

            name:a?lfred         /         name:a*d         /        name:alfred*

            注意:通配符匹配的执行效率较低,且占用内存较多,不建议使用,如果没有特殊要求,也不要将?或者*放在最前面,因为意味着要匹配所有文档,可能会造成OOM。

        7)此外,还支持正则表达式/模糊匹配/近似度查询等

            A、正则表达式:举例:/[a]?l.*/

            B、模糊匹配:fuzzy query。举例:

#模糊匹配。匹配与alfred差一个字符的词,比如:alfreds、alfret等
GET my_index/_search?q=username:alfred~1

            C、近似度查询:proximity search。举例:

#近似度查询,查询字段username和"alfred way"差n个单词的文档
GET my_index/_search?q=username:"alfred way" ~5

            使用场景常见于用户输入词的纠错中。

    2、Request Body Search

        ES自带的完备查询语句,将查询语句通过http request body发送到ES,主要参数有:

        ①query    ===>    符合Query DSL语法的查询条件

        ②from,size

        ③timeout

        ④sort

        Query DSL语法:

        基于JSON定义的查询语言,主要包含两个类型:

        1)字段类查询————如:term,match,range等。只针对一个字段进行查询

                A、全文匹配

                    针对text类型的字段进行全文检索,会对查询语句进行“先分词再查询”处理,如:match、match_phrase等

                    a、match query

                       ①对字段进行全文检索(最基本和最常用的查询类型),举例:

#match query
GET my_index/_search
{"query":{  "match":{    #关键词"username":"alfred way"    #字段名和查询语句}}
}

                       从结果,可以返回匹配文件总数,返回文档列表,_score相关性得分等。

                       一般的执行流程为:

            1.对查询语句分词==>2.根据字段的倒排索引列表,进行匹配算分==>3.汇总得分==>4.根据得分排序,返回匹配文档

                       ②使用operator参数,可以控制单词间关系,有and / or:

#使用operator参数控制单词间关系
GET my_index/_search
{"query":{"match":{"username":"alfred way","operator":"and"    #and,同时包含alfred和way}}
}

                       ③使用minimum_should_match参数控制需匹配的单词数

#使用minimum_should_match参数控制需匹配的单词数
GET my_index/_search
{"query":{"match":{"username":"alfred way","minimum_should_match":"2"}}
}

                    b、相关性算分,其本质就是一个排序问题

                        计算文档与待查询语句之间的相关度,一般有四个重要概念:

                        a、Term Frequency 词频(正相关)

                        b、Document Frequency 文档频率(负相关)

                        c、Inverse Term Frequency 逆文本频率(正相关)

                        d、Field-length Norm 文档长度(负相关)

                        目前ES有两个相关性算分的模型:

                        ①TF/IDF模型。经典模型。

                        在使用kibana进行查询时,使用explain参数,可以查看具体的计算方法。

#使用explain参数,可以查看具体的相关性的得分是如何计算的
GET my_index/_search
{"explain":true,    #设置为true"query":{"match":{"username":"alfred"}}
}

                        注意:ES计算相关性得分是根据shard进行的,即分片的分数计算相互独立,所以在使用的时候要注意分片数,可以通过设定分片数为1来避免这个问题,主要是为了观察,不代表之后所有的分片全都设为1。一般放在创建索引后,未加数据之前。

#设定shards数量为1
PUT my_index
{"settings":{"number_of_shards":"1"}
}

                        ②BM25模型。5.x版本后的默认模型,是对TF/IDF的优化模型。best match,25指:迭代了25次才计算。

                        BM25的使用,降低了TF/IDF中因为TF过大导致的负面影响,在BM25中,一个单词的TF一直增长,到一定程度就趋于0变化。

                    c、match phrase query

                        对字段做全文检索,有顺序要求。

#使用match——phrase查询词语
GET my_index/_search
{"query":{"match_phrase":{    #关键词"job":"java engineer"}}
}

                        通过使用slop参数,可以控制单词间间隔:

#使用slop参数,控制词语中的单词间隔
GET my_index/_search
{"query":{"match_phrase":{"job":{"query":"java engineer","slop":"1"    #关键词,设定单词间隔}}}
}

                    d、query string query

                        类似于URI Search中的q参数查询,举例:

#使用query_string查询
GET my_index/_search
{"query":{"query_string":{"default_field":"username","query":{alfred AND way"}}
}
#或
GET my_index/_search
{"query":{"query_string":{"fileds":["username","job"],"query":"alfred OR (java AND ruby)"}}
}

                    e、simple query string query

                        类似于query string,但会忽略错误的查询语法,且仅支持部分查询语句。使用+,|,-分别代替AND,OR,NOT。

                举例:

#使用simple query string query
GET my_index/_search
{"query":{"simple_query_string":{"fields":[username],"query":"alfred +way"    #等价于 "query":"alfred AND way"}}
}

                B、单词匹配

                    a、term/terms query

                        将待查询语句作为整个单词进行查询,不做分词处理,举例:

#使用term进行单查询
GET my_index/_search
{"query":{"term":{"username":"alfred"}}
}
#使用terms进行多查询
GET my_index/_search
{"query":{"terms":{"username":["alfred","way"]}}
}

                        此时如果直接使用alfred way作为username查询条件,是不会返回任何文档的。因为在username的倒排索引列表中,存在"alfred"和"way"的索引,但是不存在"alfred way"的索引。

                    b、range query

                        范围查询,主要针对数值类型和日期类型。

                        gt: greater than 大于

                        gte: greate than or equal to 大于等于

                        lt: less than 小于

                        lte: less than or equal to 小于等于

                        ①对数值的查询

#range query对数值的查询
GET my_index/_search
{"query":{"range":{"age":{"gte":10,"lte":20}}}
}

                        ②对日期的查询

#range query对日期的查询
GET my_index/_search
{"query":{"range":{"birth":{"lte":"1988-01-01"   #或者使用  "lte":"now-30y",这种Date Math类型}}}
}

                        Date Math类型:针对日期提供的一种更友好的计算方式。

                        当前时间用now代替,具体时间的引用,需要使用||间隔。年、月、日、时、分、秒跟date一致:y、M、w、d、h、m、s。举例:

#假设当前时间为2018-01-02 12:00:00
now+1h   =>   2018-01-02 13:00:00
now-1h   =>   2018-01-02 11:00:00
now-1h/d =>   2018-01-02 00:00:00
2016-01-01||+1M/d  => 2016-02-01 00:00:00

                    2)复合查询————如:bool查询等。包含一个/多个字段类查询/符合查询语句

                A、constant_score query

                    将内部的查询结果文档得分全部设定为1或boost的值。返回的相关性得分全部为1或boost

#使用constant_score query
GET my_index/_Search
{"query":{"constant_score":{    #关键词"match":{"username":"alfred"}}}
}

                B、bool query

                    由一个/多个布尔子句组成,主要包含以下四个:

                    a、filter                     只过滤符合条件的文档,不计算相关性得分,返回的相关性得分全部为0;

                        ES会对filter进行智能缓存,因此执行效率较高,在做简单匹配查询且不考虑得分的时候没推荐使用filter代替query

#使用filter查询
GET my_index/_search
{"query":{"bool":{    #关键词"filter":["term":{"username":"alfred"}]}}
}

                    b、must                    文档必须符合must中的所有条件,影响相关性得分;

                       

#使用must进行查询
GET my_index/_search
{"query":{"bool":{"must":[    {"match":{"username":"alfred"}},{"match":{"job":"specialist"}}]}}
}

                    c、must_not             文档必须排除must_not中的所有条件; 

#使用must_not进行查询
GET my_index/_search
{"query":{"bool":{"must":[{"match":{"job":"java"}}],"must_not":[{"match":{"job":"ruby"}}]}}
}

                    d、should                 文档可以符合should中的条件,影响相关性得分,分为两种情况:

                       同时配合minimum_should_match控制满足调价你的个数/百分比。

                       ①bool查询中只有should,不包含must的情况

                           

#bool查询中只有should的情况
GET my_index/_search
{"query":{"bool":{"should":[{"term":{"job":"java"}    #条件1},{"term":{"job":"ruby"}    #条件3}{"term":{"job":"specialist"}    #条件3}],"minimum_should_match":2    #至少需要满足两个条件}}
}

                       ②bool查询中既有should,又包含must的情况,文档不必满足should中的条件,但是如果满足的话则会增加相关性得分。

#bool查询中同时包含should和must
GET my_index/_search
{"query":{"bool":{"should":[    #同时包含should{"term":{"job":"ruby"}}],"must":[    #同时包含must{"term":{"usernmae":"alfred"}}]}}
}

                当一个查询语句位于query或filter上下文的时候,ES的执行结果也不同。

query查找和查询语句最匹配的文档,并对所有文档计算相关性得分query
bool中的:must/should
filter查找和查询语句最匹配的文档bool中的:filter/must_not
constant_score中的:filter

 

#query和filter上下文
GET my_index/_search
{"query":{"bool":{"must":[    #query上下文{"term":{"title":"Search"}},{"term":{"content":"ElasticSearch"}}],"filter":[    #filter上下文{"term":{"status":"published"}},{"range":{"publish_date":{"gte":"2015-01-01"}}}]}}
}

                D、count API

                获取符合条件的文档书,使用endpoint:_count。

#使用_count获取符合条件的文档数
GET my_index/_count    #关键词
{"query":{"match":{"username":"alfred"}}
}

                E、Source Filtering

                过滤返回结果中的_source中的字段,主要由以下两种方式:

                    a、GET my_index/_search?_source=username        #url参数

                    b、使用Request Body Search:

#不返回_source
GET my_index/_search
{"_source":false
}
#返回_source部分字段
GET my_index/_search
{"_source":["username","age"]
}
#通配符匹配返回_source部分字段
GET my_index/_search
{"_source":{"includes":"*I*","encludes":"birth"}
}

 

这篇关于《ElasticStack从入门到实践》学习笔记4的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/827427

相关文章

Python实现Word转PDF全攻略(从入门到实战)

《Python实现Word转PDF全攻略(从入门到实战)》在数字化办公场景中,Word文档的跨平台兼容性始终是个难题,而PDF格式凭借所见即所得的特性,已成为文档分发和归档的标准格式,下面小编就来和大... 目录一、为什么需要python处理Word转PDF?二、主流转换方案对比三、五套实战方案详解方案1:

SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南

《SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南》本文将基于开源项目springboot-easyexcel-batch进行解析与扩展,手把手教大家如何在SpringBo... 目录项目结构概览核心依赖百万级导出实战场景核心代码效果百万级导入实战场景监听器和Service(核心

Java Stream 的 Collectors.toMap高级应用与最佳实践

《JavaStream的Collectors.toMap高级应用与最佳实践》文章讲解JavaStreamAPI中Collectors.toMap的使用,涵盖基础语法、键冲突处理、自定义Map... 目录一、基础用法回顾二、处理键冲突三、自定义 Map 实现类型四、处理 null 值五、复杂值类型转换六、处理

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类