文章目录

  • ElasticSearch-查询语法(词项查询)
  • term
  • terms
  • exists
  • prefix
  • wildcard(通配符)
  • regexp(正则表达式)
  • fuzzy(距离)


ElasticSearch-查询语法(词项查询)

全文查询在执行查询之前会分析查询字符串,词项查询时对倒排索引中存储的词项进行精确匹配操作。词项级别的查询通常用于结构化数据,如数字、日期和枚举类型。

term

term 查询用来查找指定字段中包含给定单词的文档,term 查询不被解析,只有查询词和文档中的词精确匹配才会被搜索到,应用场景为查询人名、地名等需要精准匹配的需求。比如,查询 title 字段中含有关键词“思想”的书籍,查询命令如下:

GET books/_search
{
  "query": {
    "term": {
      "title": "思想"
    }
  }
}

避免 term 对 text 类型的字段使用查询。

默认情况下,Elasticsearch 针对 text 字段的值进行解析分词,这会使查找 text 字段值的精确匹配变得困难。

要搜索 text 字段值,需改用 match 查询。

terms

terms 查询是 term 查询的升级,可以用来查询文档中包含多个词的文档。比如,想查询 title 字段中包含关键词 “java” 或 “python” 的文档,构造查询语句如下:

GET books/_search
{
  "query": {
    "terms": {
      "title": ["java", "python"]
    }
  }
}

exists

exists 查询指定字段的数据不是空的, 由于各种原因,文档的字段可能不存在索引值:

  • 源 JSON 中的字段为 null[]
  • 字段在映射中有 "index" : false 的设置
  • 字段值的长度超过了映射中的 ignore_above 设置
  • 字段值格式不正确,并且在映射中定义了 ignore_malformed
{
  "query": {
    "exists": {
      "field": "user"
    }
  }
}

prefix

prefix 查询用于查询某个字段中以给定前缀开始的文档,比如查询 title 中含有以 java 为前缀的关键词的文档,那么含有 java、javascript、javaee 等所有以 java 开头关键词的文档都会被匹配。查询 description 字段中包含有以 win 为前缀的关键词的文档,查询语句如下:

GET books/_search
{
  "query": {
    "prefix": {
      "description": "win"
    }
  }
}

wildcard(通配符)

wildcard query 中文译为通配符查询,支持单字符通配符和多字符通配符,? 用来匹配一个任意字符,* 用来匹配零个或者多个字符。

以 H?tland 为例,Hatland、Hbtland 等都可以匹配,但是不能匹配 Htland,? 只能代表一位。H*tland 可以匹配 Htland、Habctland 等,* 可以代表 0 至多个字符。和 prefix 查询一样,wildcard 查询的查询性能也不是很高,需要消耗较多的 CPU 资源。

下面举一个 wildcard 查询的例子,假设需要找某一作者写的书,但是忘记了作者名字的全称,只记住了前两个字,那么就可以使用通配符查询,查询语句如下:

GET books/_search
{
  "query": {
    "wildcard": {
      "author": "李永*"
    }
  }
}

regexp(正则表达式)

Elasticsearch 也支持正则表达式查询,通过 regexp query 可以查询指定字段包含与指定正则表达式匹配的文档。可以代表任意字符, “a.c.e” 和 “ab…” 都可以匹配 “abcde”,a{3}b{3}、a{2,3}b{2,4}、a{2,}{2,} 都可以匹配字符串 “aaabbb”。

例如需要匹配以 W 开头紧跟着数字的邮政编码,使用正则表达式查询构造查询语句如下:

GET books/_search
{
  "query": {
    "regexp": {
      "postcode": "W[0-9].+"
    }
  }
}

fuzzy(距离)

编辑距离又称 Levenshtein 距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。fuzzy 查询就是通过计算词项与文档的编辑距离来得到结果的,但是使用 fuzzy 查询需要消耗的资源比较大,查询效率不高,适用于需要模糊查询的场景。举例如下,用户在输入查询关键词时不小心把 “javascript” 拼成 “javascritp”,在存在拼写错误的情况下使用模糊查询仍然可以搜索到含有 “javascript” 的文档,查询语句如下:

GET books/_search
{
  "query": {
    "fuzzy": {
      "title": "javascript"
    }
  }
}