前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES系列11:Term-level queries 之 3种模糊查询和terms_set query

ES系列11:Term-level queries 之 3种模糊查询和terms_set query

作者头像
方才编程_公众号同名
发布2020-11-13 10:36:59
2.1K0
发布2020-11-13 10:36:59
举报
文章被收录于专栏:方才编程
带着问题学习才高效

1、wildcard query、prefix query、fuzzy query 这3种模糊查询的异同点是什么?

2、如何使用 terms_set query 检索Array类型的字段?

ps:文末有关于Term-level queries所有查询的总结!

本文导航

01 wildcard query

检索包含通配符表达式未分析)字段的文档。【ps:等价于mysql 的 like 查询

通配符 *:它匹配任何字符序列(包括空字符) 占位符 ?:它匹配任何单个字符

请注意,此查询的速度可能很慢,因为它需要迭代许多项。为了防止极慢的通配符查询,通配符术语不应以通配符*或?之一开头。

wildcard query是很好理解的,简单看两个示例,学会DSL语句的编写即可。

1)通配符 *

代码语言:javascript
复制
GET /blogs_index/_search
{
    "query": {
        "wildcard" : { "author": "方*" }
    }
}

上述DSL语句,可以检索到所有文档。等价于sql【where author like "方%”】

2)占位符 ?

代码语言:javascript
复制
GET /blogs_index/_search
{
    "query": {
        "wildcard" : { "author": "方?" }
    }
}

上述DSL语句,检索结果为空。等价于sql【where author like "方_”】

02 prefix query

查找指定字段包含以指定确切前缀开头的术语的文档。

代码语言:javascript
复制
GET /_search
{ "query": {
    "prefix" : { "author": "方" }
  }
}

该DSL等价于 wildcard query 的 "wildcard" : { "author": "方*" },等价于sql【where author like "方%”】

03 fuzzy query

模糊查询使用基于Levenshtein编辑距离的相似度。是一种误拼写时的fuzzy模糊搜索技术用于搜索的时候可能输入的文本会出现误拼写的情况。比如输入"方财兄",这时候也要匹配到“方才兄”

通过简单示例,理解 fuzzy query:

代码语言:javascript
复制
GET /blogs_index/_search
{
    "query": {
        "fuzzy" : {
            "author": {
                "value": "方财兄",
                "fuzziness": 1,
                "prefix_length": 1,
                "max_expansions": 100
            }
        }
    }
}

参数解释:

fuzziness:最大编辑距离【一个字符串要与另一个字符串相同必须更改的一个字符数】。默认为AUTO。 prefix_length:不会被“模糊化”的初始字符数。这有助于减少必须检查的术语数量。默认为0。 max_expansions:fuzzy查询将扩展到的最大术语数。默认为50。 transpositions:是否支持模糊转置(ab→ ba)。默认值为false。

上述DSL等价于sql【where author like “方_兄”or author like “方财_”or author like “方_财兄”or author like “方财_兄”or author like “方财兄_”】(会根据上述的4个参数穷尽所有可能组合

注意:如果prefix_length将设置为0,并且max_expansions将设置为很高的数字,则此查询可能会很繁琐。这可能会导致索引中的每一项都受到检查!

04 exists query

1)查找指定字段包含任何非空值【不是null 也不是[ ]】的文档。【ps:等价于mysql 的 is null】

注意:这些值不属于空值

1、空字符串,例如""或"-" 2、包含null和另一个值的数组,例如[null, "foo"] 3、自定义null-value,在字段映射中定义

简单看个示例,学会DSL语句的编写即可:

代码语言:javascript
复制
1、查询 title字段不为 null 的文档
GET /blogs_index/_search
{
    "query": {
        "exists" : { "field" : "title" }
    }
}

2)查询为null的字段,应该使用:must_not + exists【ps:关于bool语句,TeHero在明天将为大家分享】

代码语言:javascript
复制
GET /blogs_index/_search
{
    "query": {
        "bool": {
            "must_not": {
                "exists": {
                    "field": "title"
                }
            }
        }
    }
}

05 terms_set query

返回的文档至少匹配一个或多个检索的术语。这些术语未进行分析,因此必须完全匹配。每个文档中必须匹配的术语数会有所不同,并由“最小匹配项”字段控制,或者由“最小匹配项”脚本中的每个文档计算。

ps:terms_set query 在对Array类型的字段做检索时非常有用,特别是对于每个文档,需要匹配的数量不一致时。如果所有文档需要匹配的数量一致,可以使用match query替代

1) 数据准备

代码语言:javascript
复制
PUT /term_set_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "codes": {
          "type": "keyword"
        },
        "required_matches": {
          "type": "integer"
        }
      }
    }
  }
}

PUT /term_set_index/_doc/1?refresh
{
    "codes": ["系统学习", "es","关注我"],
    "required_matches": 2
}
PUT /term_set_index/_doc/2?refresh
{
    "codes": ["系统", "学习"],
    "required_matches": 1
}

ps:控制必须匹配术语的数量的字段必须是数字字段

2) minimum_should_match_field

代码语言:javascript
复制
GET /term_set_index/_search
{
  "query": {
    "terms_set": {
      "codes": {
        "terms": [
          "关注我",
          "学习"
        ],
        "minimum_should_match_field": "required_matches"
      }
    }
  }
}

分析:该DSL语句可以检索到文档2。 对于文档1,需要至少匹配2个term,但是在检索terms里,只能匹配上【关注我】一个term,所以文档1不符合检索条件 对于文档2,只需要匹配一个term,刚好能匹配上检索terms里的【学习】。

3) minimum_should_match_script

代码语言:javascript
复制
GET /term_set_index/_search
{
  "query": {
    "terms_set": {
      "codes": {
        "terms": [
          "系统学习",
          "关注我"
        ],
        "minimum_should_match_script": {
          "source": " doc['required_matches'].value"
        }
      }
    }
  }
}

等价于上一句DSL。

4) 与match query的比较

当每个文档的required_matches值都相同时,上述两句DSL与下面的match query 语句检索效果完全一致:

代码语言:javascript
复制
GET /term_set_index/_search
{
    "query": {
        "match": {
            "codes" : {
                "query":  "系统学习 关注我",
                "analyzer": "whitespace",
                "minimum_should_match": 2
            }
        }
    }
}

分析:DSL语句使用 "analyzer": "whitespace", 所以 query会被分词两个Token/term【系统学习】【关注我】。"minimum_should_match": 2,所以可以检索到文档1。

ps:关于Term-level queries 与 Full Text queries 的对比分析,使用场景对比,后续TeHero将详细为大家讲解!敬请期待哟!

07 仅用于了解的term-level queries

1) regexp query——使用正则表达式术语查询

代码语言:javascript
复制
GET /_search
{
    "query": {
        "regexp":{
            "name.first": "s.*y"
        }
    }
}

注意:regexp查询的性能在很大程度上取决于所选的正则表达式。匹配所有类似的东西.*都很慢,而且使用环视正则表达式也很慢。如果可能,应在正则表达式开始之前尝试使用长前缀。【ps,正在表达式,在日志系统使用较多,后面在Logstash系列,TeHero再为大家讲解】

2) type query

筛选与提供的文档/映射类型匹配的文档。【几乎无用,因为 type 在7.x已被弃用,并将在8.x版本中被删除】

代码语言:javascript
复制
GET /your_index/_search
{
    "query": {
        "type" : {
            "value" : "_doc"
        }
    }
}

3) ids query

根据index的 _id 字段检索文档

代码语言:javascript
复制
GET /_search
{
    "query": {
        "ids" : {
            "type" : "_doc",
            "values" : ["1", "4", "100"]
        }
    }
}

08 总结

到此我们已经学完 Term-level queries 的11种查询,下面我们进行一个简单的总结:

1、 所有的 Term-level queries 的检索关键词都不会分词; 2、term query 等价于sql【where Token = “检索词”】; 3、terms query 等价于sql【where Token in ( 检索词List )】; 4、range query 掌握Date Math 和对 range类型字段检索的 relation参数; 5、掌握 wildcard query、prefix query、fuzzy query 这3种模糊查询; 6、terms_set query 用于检索Array类型的字段,但文档中必须定义一个数字字段——表示最低匹配的term数量; 7、exists query 用于检索为null的字段,检索不为null的字段使用 must_not + exists。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 方才编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档