Elasticsearch基本查询总结

时间:2021-07-30
本文章向大家介绍Elasticsearch基本查询总结,主要包括Elasticsearch基本查询总结使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Elasticsearch是一个分布式文档存储。Elasticsearch不会将信息存储为列数据的行,而是存储已序列化为JSON文档的复杂数据结构。当集群中有多个Elasticsearch节点时,存储的文档将分布在集群中,并且可以从任何节点立即访问。
存储文档时,将在1秒钟内几乎实时地对其进行索引和完全搜索。Elasticsearch使用称为倒排索引的数据结构,该结构支持非常快速的全文本搜索。反向索引列出了出现在任何文档中的每个唯一单词,并标识了每个单词出现的所有文档。
索引可以认为是文档的优化集合,每个文档都是字段的集合,这些字段是包含数据的键值对。默认情况下,Elasticsearch对每个字段中的所有数据建立索引,并且每个索引字段都具有专用的优化数据结构。例如,文本字段存储在倒排索引中,数字字段和地理字段存储在BKD树中。使用按字段数据结构组合并返回搜索结果的能力使Elasticsearch如此之快。
Elasticsearch还具有无模式的能力,这意味着无需显式指定如何处理文档中可能出现的每个不同字段即可对文档建立索引。启用动态映射后,Elasticsearch自动检测并向索引添加新字段。此默认行为使索引和浏览数据变得容易-只需开始建立索引文档,Elasticsearch就会检测布尔值,浮点数和整数值,日期和字符串并将其映射到适当的Elasticsearch数据类型。

1.1 精确值查找
1.1.1 单个精确值查找(term query)
term 查询会查找我们指定的精确值。term 查询是简单的,它接受一个字段名以及我们希望查找的数值。
想要类似mysql中如下sql语句的查询操作:
SELECT document FROM products WHERE price = 20;

当进行精确值查找时, 我们会使用过滤器(filters)。过滤器很重要,因为它们执行速度非常快,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存。如下: 使用 constant_score 查询以非评分模式来执行 term 查询并以一作为统一评分。

GET /my_store/products/_search
{
  "query" : {
  "constant_score" : {
  "filter" : {
  "term" : {
  "price" : 20
  }
  }
  }
  }

注意:5.xES中,对于字符串类型,要进行精确值匹配。需要讲类型设置为text和keyword两种类型。mapping设置如下:

 

POST testindex/testtype/_mapping
{
"testtype ":{
"properties":{
"title":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_max_word",
"fields":{
"keyword":{
"type":"keyword"
}
}
}
}

精确值java api jest使用方法:
searchSourceBuilder.query(QueryBuilders.termQuery(“text.keyword”, “来自新华社的报道”));

1.1.2 布尔过滤器
一个 bool 过滤器由三部分组成:

{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : [],
      "filter":    []
   }
}

must ——所有的语句都 必须(must) 匹配,与 AND 等价。
must_not ——所有的语句都 不能(must not) 匹配,与 NOT 等价。
should ——至少有一个语句要匹配,与 OR 等价。
filter——必须匹配,运行在非评分&过滤模式。
就这么简单! 当我们需要多个过滤器时,只须将它们置入 bool 过滤器的不同部分即可。
举例:

GET /my_store/products/_search
{
  "query" : {
  "filtered" : {
  "filter" : {
  "bool" : {
  "should" : [
  { "term" : {"price" : 20}},
 
  { "term" : {"productID" : "XHDK-A-1293-#fJ3"}}
 
  ],
  "must_not" : {
  "term" : {"price" : 30}
 
  }
  }
  }
  }
  }

1.1.3 多个值精确查找(terms query)

{
  "terms" : {
  "price" : [20, 30]
  }
}

如上,terms是包含的意思,包含20或者包含30。
如下实现严格意义的精确值检索, tag_count代表必须匹配的次数为1。

GET /my_index/my_type/_search
{
  "query": {
  "constant_score" : {
  "filter" : {
  "bool" : {
  "must" : [
  { "term" : { "tags" : "search" } },
  { "term" : { "tag_count" : 1 } }
  ]
  }
  }
  }
  }
}

1.2 范围检索(range query)
range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:

gt: > 大于(greater than)
lt: < 小于(less than)
gte: >= 大于或等于(greater than or equal to)
lte: <= 小于或等于(less than or equal to)

类似Mysql中的范围查询:

SELECT document
FROM products
WHERE price BETWEEN 20 AND 40

ES中对应的DSL如下:

GET /my_store/products/_search
{
  "query" : {
  "constant_score" : {
  "filter" : {
  "range" : {
  "price" : {
  "gte" : 20,
  "lt" : 40
  }
  }
  }
  }
  }
}

1.3 存在与否检索(exist query)
mysql中,有如下sql:
SELECT tags FROM posts WHERE tags IS NOT NULL;
ES中,exist查询某个字段是否存在:

GET /my_index/posts/_search
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "exists" : { "field" : "tags" }
            }
        }
    }
}

若想要exist查询能匹配null类型,需要设置mapping:

"user": {
  "type": "keyword",
  "null_value": "_null_"
}

missing查询在5.x版本已经不存在,改成如下的判定形式:

GET /_search
{
    "query": {
        "bool": {
            "must_not": {
                "exists": {
                    "field": "user"
                }
            }
        }
    }
}

1.4 前缀检索( Prefix Query )
匹配包含 not analyzed 的前缀字符:

GET /_search
{ "query": {
"prefix" : { "user" : "ki" }
}
}

1.5 通配符检索( wildcard query)
匹配具有匹配通配符表达式( (not analyzed )的字段的文档。 支持的通配符:
1)*,它匹配任何字符序列(包括空字符序列);
2)?,它匹配任何单个字符。
请注意,此查询可能很慢,因为它需要遍历多个术语。
为了防止非常慢的通配符查询,通配符不能以任何一个通配符*或?开头。
举例:

GET /_search
{
"query": {
"wildcard" : { "user" : "ki*y" }
}
}

1.6 正则表达式检索(regexp query)
正则表达式查询允许您使用正则表达式术语查询。
举例如下:

GET /_search
{
"query": {
"regexp":{
"name.first": "s.*y"
}
}
}

注意: *的匹配会非常慢,你需要使用一个长的前缀,
通常类似.*?+通配符查询的正则检索性能会非常低。
1.7 模糊检索(fuzzy query)
模糊查询查找在模糊度中指定的最大编辑距离内的所有可能的匹配项,然后检查术语字典,以找出在索引中实际存在待检索的关键词。
举例如下:

GET /_search
{
"query": {
"fuzzy" : { "user" : "ki" }
}
}

1.8 类型检索(type query)
举例:

GET /my_index/_search
{
"query": {
"type" : {
"value" : "xext"
}
}
}

已验证,检索索引my_index中,type为xext的全部信息。
1.9 Ids检索(ids query)
返回指定id的全部信息。

GET /my_index/_search
{
"query": {
"ids" : {
"type" : "xext",
"values" : ["2", "4", "100"]
}
}
}

2、全文检索
高级全文查询通常用于在全文本字段(如电子邮件正文)上运行全文查询。他们了解如何对被查询的字段进行分析,并在执行前将每个字段的分析器(或search_analyzer)应用于查询字符串。
2.1 匹配检索(match query)
匹配查询接受文本/数字/日期类型,分析它们,并构造查询。
1)匹配查询的类型为boolean。 这意味着分析所提供的文本,并且分析过程从提供的文本构造一个布尔查询,
可以将运算符标志设置为或以控制布尔子句(默认为或);
2)文本分析取决于mapping中设定的analyzer(中文分词,我们默认选择ik分词器);
3) fuzziness——模糊性允许基于被查询的字段的类型进行模糊匹配;
4)”operator”: “and”——匹配与操作(默认或操作);
5) “minimum_should_match”: “75%”——这让我们可以指定必须匹配的词项数用来表示一个文档是否相关。
举例:

郭慕荣博客园

原文地址:https://www.cnblogs.com/jelly12345/p/15078217.html