【Elastic Search】 查询详解(DSL Query)

目录

关于索引

检索原理

搜索方式

全文检索(Full text queries)

Term查询

复合查询

Geo查询

形状查询

Join查询

Span查询(跨度查询)

专用查询(Specialized queries)

使用场景分析


关于索引

以语料:【东芝电子元件(上海)有限公司,TOSHIBA ELECTRONIC DEVICES & STORAGE CORPORATION】 为例,在不同的分析器下,会生成不同的索引,具体如下。

解析器分词结果token数量
keyword[东芝电子元件(上海)有限公司,TOSHIBA ELECTRONIC DEVICES & STORAGE CORPORATION]1
standard[东,芝,电,子,元,件,上,海,有,限,公,司,toshiba,electronic,devices,storage,corporation]17
ik_max_word[东芝,电子元件,电子,元件,上海,有限公司,有限,公司,toshiba,electronic,devices,storage,corporation]13
ngram(1,50)[东,东芝,东芝电,东芝电子,东芝电子元,东芝电子元件,东芝电子元件(,东芝电子元件(上,东芝电子元件(上海,东芝电子元件(上海)…]1925
ngram(2,50)[东芝,东芝电,东芝电子,东芝电子元,东芝电子元件,东芝电子元件(,东芝电子元件(上,东芝电子元件(上海,东芝电子元件(上海),东芝电子元件(上海)有…]1862
自定义,仅根据空格和逗号分隔[东芝电子元件(上海)有限公司,toshiba,electronic,devices,&,storage,corporation]7

各解析器特点:

  1. keyword:Keyword 解析器保留输入文本作为一个完整的词汇单元,不进行分词,且不主动转换大小写。
  2. standard:Standard 解析器根据空白字符和标点符号进行分词,并将文本转换为小写
  3. ik_max_word:IK Max Word 解析器是一种中文分词器,可以处理中文文本
  4. ngram:Ngram 解析器按照指定的最小和最大 n-gram 大小创建分词结果,这里生成的token数量较大,但实际查询使用并不一定会全部用到。
  5. 自定义解析器:这里自定义规则仅根据空格和逗号分隔,其生成结果的效果不一定好,可以根据实际需要进行自定义。

检索原理

参考:文本分析概念(Concepts)

搜索方式

全文检索(Full text queries

查询方式原始名称引入版本/废弃特点描述匹配示例匹配说明备注
间隔查询intervals已经废弃
匹配查询match对字段进行全文匹配,不考虑分词"hello world"匹配文档中包含 "hello world" 的文本
匹配布尔前缀查询match_bool_prefix7.10.0对字段进行全文匹配,只考虑前缀"hel"匹配文档中以 "hel" 开头的文本要求查询字符串中的词语顺序不变。
匹配短语查询match_phrase对字段进行全文匹配,要求短语中的所有词语都出现,且词语顺序不变"hello world"匹配文档中包含 "hello world" 的连续文本要求查询字符串中的词语顺序不变。
匹配短语前缀查询match_phrase_prefix1.4.0对字段进行全文匹配,要求短语中的所有词语都出现,但词语顺序可以变"hel* wor*d"匹配文档中包含 "hello world"、"hello worldd"、"hello worl" 等文本对查询字符串中的词语顺序要求更宽松
多字段匹配查询multi_match1.0.0对多个字段进行全文匹配"hello world"匹配文档中包含 "hello world" 的文本,无论该文本出现在哪个字段中多字段匹配查询可以提高查询效率,但也可能会降低查询精度
组合字段查询combined_fields7.4.0对多个字段进行组合查询,可以是任意类型的查询match("title", "hello world")匹配文档中包含 "hello world" 的标题可以实现更复杂的查询逻辑
字符串查询query_string使用查询字符串进行查询"title:hello OR content:world"匹配文档中标题包含 "hello" 或内容包含 "world"可以查询字符串,但也可能会降低查询效率。
简单查询字符串查询simple_query_string简化版的查询字符串查询"hello world"匹配文档中包含 "hello world" 的文本字符串查询的简化版,功能更弱

Term查询

查询方式原始名称引入版本特点描述匹配示例匹配描述备注
存在查询exists0.90.0查询字段是否存在exists("title")匹配所有包含标题的文档
模糊查询fuzzy0.10.0模糊匹配fuzzy("title", "hello world")匹配包含 "hello world" 的文档,允许部分文本不匹配允许部分文本不匹配
ID 查询ids0.10.0按文档 ID 查询ids("1234567890", "9876543210")匹配文档 ID 为 "1234567890" 或 "9876543210" 的文档
前缀查询prefix0.10.0前缀匹配prefix("title", "hello")匹配标题以 "hello" 开头的文档用于前缀匹配
范围查询range0.10.0范围匹配range("age", 18, 25)匹配年龄在 18 到 25 岁之间的文档用于范围匹配
正则表达式查询regexp0.10.0正则表达式匹配regexp("title", "/hello/i")匹配标题包含 "hello" 的文档,不区分大小写用于正则表达式匹配
精确查询term0.10.0精确匹配term("title", "hello world")匹配标题等于 "hello world" 的文档精确匹配
多值精确查询terms0.10.0多值精确匹配terms("title", ["hello world", "goodbye world"])匹配标题等于 "hello world" 或 "goodbye world" 的文档多值精确匹配
多值精确查询(不区分顺序)terms set6.5.0多值精确匹配,不区分顺序terms_set("title", ["hello world", "goodbye world"])匹配标题包含 "hello world" 或 "goodbye world" 的文档,不区分顺序用于多值精确匹配,不区分顺序
通配符查询wildcard0.10.0通配符匹配wildcard("title", "he*o")匹配标题以 "he" 开头,以 "o" 结尾的文档用于通配符匹配

复合查询

查询方式原始名称特点描述使用示例匹配描述备注
布尔查询bool允许组合多个查询{"bool":{"must":{"term":{"http://user.id/":"kimchy"}},"filter":{"term":{"tags":"production"}},"must_not":{"range":{"age":{"gte":10,"lte":20}}},"should":[{"term":{"tags":"env1"}},{"term":{"tags":"deployed"}}],"minimum_should_match":1,"boost":1.0}}匹配满足逻辑条件的记录最常用的查询方式
提升查询boosting为某些查询结果赋予更高的权重{"boosting":{"positive":{"term":{"text":"apple"}},"negative":{"term":{"text":"pie tart fruit crumble tree"}},"negative_boost":0.5}}将包含关键词 "apple" 的文档加权提升,同时通过降低包含词组 "pie tart fruit crumble tree" 的文档的权重可以用于突出显示某些查询结果
恒定得分查询constant_score为所有结果赋予相同的得分{"constant_score":{"filter":{"term":{"http://user.id/":"kimchy"}},"boost":1.2}}匹配标题包含 "hello" 的文档,并为所有结果赋予相同的得分可以用于提高查询效率
最大值查询dis_max从多个查询中返回得分最高的结果{"dis_max":{"queries":[{"term":{"title":"Quick pets"}},{"term":{"body":"Quick pets"}}],"tie_breaker":0.7}}通过dis_max实现了对标题和正文中包含"Quick pets"的文档进行检索,使用0.7的权重来平衡两个查询的得分。可以用于提高查询灵活性
函数得分查询function_score使用自定义函数为结果赋予得分{"function_score":{"query":{"match_all":{}},"boost":"5","random_score":{},"boost_mode":"multiply"}}使用函数分数查询,在匹配所有文档的基础上,通过乘法方式将随机分数与指定的增益因子相乘。可以用于实现复杂的查询逻辑

Geo查询

查询方式原始名称特点描述使用示例匹配描述
地理边界查询geo_bounding_box匹配指定范围内的地理位置{"geo_bounding_box":{"pin.location":{"top_left":{"lat":40.73,"lon":-74.1},"bottom_right":{"lat":40.01,"lon":-71.12}}}}匹配坐标范围在 [40.73, -74.1] 到 [40.01, -71.12] 内的文档
地理距离查询geo_distance匹配指定距离内的地理位置{"geo_distance":{"distance":"200km","pin.location":{"lat":40,"lon":-70}}}匹配距离坐标 (40, -70) 在 200 公里内的文档
地理网格查询geo_grid匹配指定网格内的地理位置{"geo_grid":{"location":{"geohash":"u0"}}}匹配坐标位于网格单元中的文档
地理多边形查询geo_polygon匹配指定多边形内的地理位置{"geo_polygon":{"person.location":{"points":[{"lat":40,"lon":-70},{"lat":30,"lon":-80},{"lat":20,"lon":-90}]}}}匹配坐标位于多边形内的文档
地理形状查询geo_shape匹配指定形状内的地理位置{"geo_shape":{"location":{"shape":{"type":"envelope","coordinates":[[13.0,53.0],[14.0,52.0]]},"relation":"intersects"}}}匹配坐标位于形状内的文档,形状可以是多边形、圆形或矩形

形状查询

查询方式原始名称特点描述使用示例匹配描述
形状查询shape匹配指定形状的文档{"shape":{"type":"envelope","coordinates":[[1355.0,5355.0],[1400.0,5200.0]]}}匹配坐标位于多边形内的文档,形状可以是多边形、圆形或矩形

Join查询

查询方式原始名称特点描述使用示例匹配描述实际示例
嵌套查询nested用于匹配嵌套文档nested("products", "price", gte(100))匹配嵌套在 "products" 字段中的文档,且 "price" 字段的值大于或等于 100{"nested":{"path":"obj1","query":{"bool":{"must":[{"match":{"http://obj1.name/":"blue"}},{"range":{"obj1.count":{"gt":5}}}]}},"score_mode":"avg"}}
子文档存在查询has_child用于匹配具有子文档的文档has_child("products")匹配具有嵌套在 "products" 字段中的文档{"has_child":{"type":"child","query":{"match_all":{}},"max_children":10,"min_children":2,"score_mode":"min"}}
父文档存在查询has_parent用于匹配具有父文档的文档has_parent("orders")匹配具有嵌套在 "orders" 字段中的文档{"has_parent":{"parent_type":"parent","query":{"term":{"tag":{"value":"Elasticsearch"}}}}}
父文档 ID 查询parent_id用于匹配指定父文档 ID 的文档parent_id("orders", "1234567890")匹配父文档 ID 为 "1234567890" 的文档{"parent_id":{"type":"my-child","id":"1"}}

Span查询(跨度查询)

Span Query(跨度查询)是一种在文档中查找特定跨度或位置的查询方式。它用于匹配文本中的一段连续片段,这些片段需要满足一定的条件。跨度查询通常用于更复杂的文本匹配需求,例如要求匹配的词语在文档中以特定的顺序或距离出现。

Span Query允许你指定一系列的条件,包括词语的存在、相对位置、顺序等。这样的查询可以用于精确地定位文档中的某些文本片段,而不仅仅是简单的词语匹配。跨度查询在信息检索领域中常用于处理更复杂的语义关系和语境匹配。

查询方式原始名称特点描述使用示例匹配描述
span 包含查询span_containing匹配包含指定文本的spanspan_containing("title", "hello world")匹配标题包含 "hello world" 的span
span 字段遮罩查询span_field_masking允许指定span的字段span_field_masking("title", ["name", "age"])匹配标题的span,但只返回 "name" 和 "age" 字段的值
span 首个查询span_first匹配文档中第一个匹配的spanspan_first("title", "hello world")匹配文档中第一个标题包含 "hello world" 的span
span 多值查询span_multi匹配文档中多个匹配的spanspan_multi("title", ["hello world", "goodbye world"])匹配文档中标题包含 "hello world" 或 "goodbye world" 的span
span 邻近查询span_near匹配文档中邻近的spanspan_near("title", ["hello world", "goodbye world"], 2)匹配文档中标题包含 "hello world" 和 "goodbye world" 的span,且这两个span的距离不超过 2
span 不包含查询span_not匹配不包含指定文本的spanspan_not("title", "hello world")匹配标题不包含 "hello world" 的span
span 或查询span_or匹配多个span之一span_or("title", ["hello world", "goodbye world"])匹配文档中包含 "hello world" 或 "goodbye world" 的任意一个span
span 术语查询span_term匹配指定术语的spanspan_term("title", "hello world")匹配标题包含术语 "hello world" 的span
span 范围查询span_within匹配范围内的spanspan_within("title", ["hello", "world"], ["goodbye", "world"])匹配标题包含术语 "hello" 或 "world" 的span,但不包含术语 "goodbye" 或 "world"

专用查询(Specialized queries)

"Specialized queries"(专用查询)通常指的是在搜索引擎或数据库中,为特定的需求或数据类型而设计的特殊查询方式。这些查询被定制或优化,以满足特定的应用场景、数据结构或搜索需求,以提高检索的效率和准确性。

在搜索引擎或数据库的上下文中,"Specialized queries" 可能涉及到针对特殊数据类型的查询,如地理数据查询、时间序列数据查询、全文搜索查询等。这些查询通常利用特定的索引结构、算法或优化策略,以更好地处理特定类型的数据。

查询方式原始名称特点描述使用示例匹配描述
距离特征查询distance_feature为文档添加距离特征distance_feature("location", "127.0,37.0", 1000)为文档添加距离特征,距离为 (127.0,37.0) 的最近 1000 米内的文档
相似度查询more_like_this查找与给定文档相似的文档more_like_this("title", ["hello world", "goodbye world"])查找与文档标题包含 "hello world" 或 "goodbye world" 的文档相似的文档
渗透查询percolate查找与给定过滤器匹配的文档percolate("filter", "title:hello world")查找与过滤器匹配的文档,过滤器为 "title:hello world"
排名特征查询rank_feature为文档添加排名特征rank_feature("popularity")为文档添加排名特征,排名根据 "popularity" 字段的值
脚本查询script使用脚本自定义查询逻辑script(script_source, script_params)使用脚本自定义查询逻辑,脚本源为 "script_source",脚本参数为 "script_params"
脚本得分查询script_score使用脚本为文档赋予得分script_score(script_source, script_params)使用脚本为文档赋予得分,脚本源为 "script_source",脚本参数为 "script_params"
包装器查询wrapper包装其他查询wrapper(query, wrapper_source)包装其他查询,查询为 "query",包装源为 "wrapper_source"
固定查询pinned固定查询结果pinned("query")固定查询结果,查询为 "query"
规则查询rule使用规则匹配文档rule(rule_source)使用规则匹配文档,规则源为 "rule_source"

使用场景分析

这里首先要去分一个概念,全文匹配与结构化检索。其中,Term相关的匹配查询都属于结构化检索,这个可以理解为将ES用作MySQL类似的数据库查询,只不过语法有所区别;而全文检索的场景有所不同,全文查询通常用于在全文本字段(如电子邮件正文)上运行全文查询。他们了解如何对被查询的字段进行分析,并在执行前将每个字段的分析器(analyzer)应用于查询字符串。

首先一个具体表现就是,对于全文检索,其搜索的词是要被analyzer分词,将分词得到的token跟原始的索引进行匹配;结构化搜索的时候,提供的搜索词不会被分词,会直接跟原始索引进行匹配。这里其实就体现出匹配比较关键的两个点,其一是构建什么样的索引才能被匹配,其二是应该用什么样的搜索方式进行查询,这两者都需要结合实际业务场景进行合理选择。

  • 31
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值