Elasticsearch 中当我们设置集群、节点完毕后,就可以按照设定的方式导入数据。

有了数据后,我们就需要对数据进行检索操作。根据实际开发需要,往往我们需要支持包含但不限于以下类型的检索: 
1)精确匹配,类似 mysql 中的 “=”操作; 
2)模糊匹配,类似 mysql 中的”like %关键词% “查询操作; 
3)前缀匹配; 
4)通配符匹配; 
5)正则表达式匹配; 
6)跨索引匹配; 
7)提升精读匹配。

ElasticSearch 中的检索类型

结构化检索

针对字段类型: 日期、时间、数字类型,以及精确的文本匹配。 
结构化检索特点: 
* 1)结构化查询,我们得到的结果 总是 非是即否,要么存于集合之中,要么存在集合之外。 
* 2)结构化查询不关心文件的相关度或评分;它简单的对文档包括或排除处理。

精确值检索

单个精确值检索

term 查询会查找我们指定的精确值。term 查询是简单的,它接受一个字段名以及我们希望查找的数值。

想要类似 mysql 中如下 sql 语句的查询操作:

SELECT document FROM products WHERE price = 20; 
DSL写法:

GET /bank/_search
{
  "query" : {
  "term" : {
  "age" : 20
  }
  }
}

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

注意:5.x以上ES中,对于字符串类型,要进行精确值匹配。需要指定类型为text或keyword两种

GET /bank/_search
{
  "query" : {
  "constant_score" : {
  "filter" : {
  "term" : {
  "age.keyword" : 20
  }
  }
  }
  }
}

布尔过滤器

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

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

must——所有的语句都 必须(must) 匹配,与 AND 等价。 
must_not——所有的语句都 不能(must not) 匹配,与 NOT 等价。 
should——至少有一个语句要匹配,与 OR 等价。 
filter——必须匹配,运行在非评分&过滤模式。  

多个精确值检索

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

如上,terms是包含的意思,包含20或者包含30 

范围检索

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

gt: > 大于(greater than)
lt: < 小于(less than)
gte: >= 大于或等于(greater than or equal to)
lte: <= 小于或等于(less than or equal to)
(类似MySql中where value between and)

存在状态检索

GET /bank/_search
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "exists" : { "address" : "LA" }
            }
        }
    }
}

前缀检索 Prefix Query

GET /_search
{ "query": {
  "prefix" : { "lastname" : "H" }
  }
}

通配符检索

?(代表单个字符)

*(代表0到多个字符)

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

正则表达式检索

举例:

GET /bank/_search
{
  "query": {
  "regexp":{
  "firstname": "s.*y"
  }
  }
}

模糊检索

模糊查询查找在模糊度中指定的最大编辑距离内的所有可能的匹配项,然后检查术语字典,以找出在索引中实际存在待检索的关键词。 
举例如下:

e.g.
GET /bank/_search
{
  "query": {
  "fuzzy" : { "first" : "ki" }
  }
}

类型检索

检索索引下对应的type 数据 (即将废弃)

IDS 检索

检索指定 id 的数据

全文检索

高级全文查询通常用于在全文本字段(如电子邮件正文)上运行全文查询。他们了解如何对被查询的字段进行分析,并在执行前将每个字段的分析器(或 search_analyzer)应用于查询字符串。

匹配检索

匹配查询接受文本/数字/日期类型,分析它们,并构造查询。 
1)匹配查询的类型为 boolean。 这意味着分析所提供的文本,并且分析过程从提供的文本构造一个布尔查询, 
可以将运算符标志设置为或以控制布尔子句(默认为或); 
2)文本分析取决于 mapping 中设定的 analyzer(中文分词,我们默认选择ik分词器); 
3) fuzziness——模糊性允许基于被查询的字段的类型进行模糊匹配; 
4)”operator”: “and”——匹配与操作(默认或操作); 
5) “minimum_should_match”: “75%”——这让我们可以指定必须匹配的词项数用来表示一个文档是否相关。

匹配解析检索

match_phrase 查询分析文本,并从分析文本中创建短语查询。 
类似 match 查询, match_phrase 查询首先将查询字符串解析成一个词项列表,然后对这些词项进行搜索,但只保留那些包含 全部 搜索词项,且位置与搜索词项相同的文档

匹配解析前缀检索

用户已经渐渐习惯在输完查询内容之前,就能为他们展现搜索结果,这就是所谓的 即时搜索(instant search) 或 输入即搜索(search-as-you-type) 。 
不仅用户能在更短的时间内得到搜索结果,我们也能引导用户搜索索引中真实存在的结果。 
例如,如果用户输入 johnnie walker bl ,我们希望在它们完成输入搜索条件前就能得到: 
Johnnie Walker Black Label 和 Johnnie Walker Blue Label 。

match_phrase_prefix 与 match_phrase 相同,除了它允许文本中最后一个术语的前缀匹配。 

多字段匹配检索

支持字段模糊匹配

multi_match 查询为能在多个字段上反复执行相同查询提供了一种便捷方式。 
默认情况下,查询的类型是 best_fields, 这表示它会为每个字段生成一个 match 查询。 
举例1:”fields”: “*_title” 
——任何与模糊模式正则匹配的字段都会被包括在搜索条件中, 例如可以左侧的方式同时匹配 book_title 、 chapter_title 和 section_title (书名、章名、节名)这三个字段。 
举例2: “fields”: [ “*_title”, “chapter_title^2” ] 
——可以使用 ^ 字符语法为单个字段提升权重,在字段名称的末尾添加 ^boost , 其中 boost 是一个浮点数。 
举例3:”fields”: [ “first_name”, “last_name” ], 
“operator”: “and” 
——两个字段必须都包含。

字符串检索

一个使用查询解析器解析其内容的查询。 
query_string 查询提供了以简明的简写语法执行多匹配查询 multi_match queries ,布尔查询 bool queries ,提升得分 boosting ,模糊匹配 fuzzy matching ,通配符 wildcards ,正则表达式 regexp 和范围查询 range queries 的方式。 
支持参数达10几种

简化字符串检索

一个使用 SimpleQueryParser 解析其上下文的查询。 与常规 query_string 查询不同,simple_query_string 查询永远不会抛出异常,并丢弃查询的无效部分。 
支持的操作如下: 
1)+表示AND操作 
2)| 表示OR操作 
3)- 否定操作 
4)*在术语结束时表示前缀查询 
5)()表示优先

复合检索

Joining 检索

在像 Elasticsearch 这样的分布式系统中执行完整的 sql 风格的连接是非常浪费的。然而,Elasticsearch 提供了两种形式的连接,用于连接查询。

nested 查询

嵌套查询允许查询嵌套对象/文档。查询在嵌套对象/文档上执行,就像它们作为单独的文档被索引一样(在内部),并生成根父文档(或父嵌套映射)

//建立一个索引
PUT /my_index
{
    "mappings": {
        "_doc" : {
            "properties" : {
                "obj1" : {
                    "type" : "nested"
                }
            }
        }
    }
}
//使用嵌套查询
GET /_search
{
    "query": {
        "nested" : {
            "path" : "obj1",
            "score_mode" : "avg",
            "query" : {
                "bool" : {
                    "must" : [
                    { "match" : {"obj1.name" : "blue"} },
                    { "range" : {"obj1.count" : {"gt" : 5}} }
                    ]
                }
            }
        }
    }
}

 

has_child 查询

has_child 过滤器接受查询和要运行的子类型,并生成具有匹配查询的子文档的父文档

GET /_search
{
    "query": {
        "has_child" : {
            "type" : "blog_tag",
            "query" : {
                "term" : {
                    "tag" : "something"
                }
            }
        }
    }
}

has_child 还具有评分支持。支持的评分模式有 min、max、sum、avg 或 none。默认值为 none,并产生与以前版本相同的行为。如果将 score 模式设置为另一个值,而不是 none,则将所有匹配的子文档的得分聚合到关联的父文档中。

has_parent 查询

has_parent 查询接受一个查询和一个父类型。查询在父文档空间中执行,该空间由父类型指定。该查询返回关联的父文档匹配的子文档。对于其余的 has_parent 查询具有与 has_child 查询相同的选项和工作方式。

GET /_search
{
    "query": {
        "has_parent" : {
            "parent_type" : "blog",
            "query" : {
                "term" : {
                    "tag" : "something"
                }
            }
        }
    }
}

GEO 检索(地理形状查询)

过滤使用 geo_shape 类型索引的文档。

需要 geo_shape 映射。

geo_shape 查询使用与 geo_shape 映射相同的网格正方形表示来查找具有与查询形状相交的形状的文档。它还将使用与字段映射所定义的相同的前缀树配置。

该查询支持两种定义查询形状的方法,一种是提供完整的形状定义,另一种是引用在另一个索引中预先索引的形状的名称。下面将通过示例定义这两种格式。

//新建一个索引
PUT /example
{
    "mappings": {
        "_doc": {
            "properties": {
                "location": {
                    "type": "geo_shape"
                }
            }
        }
    }
}
//插入一条记录
POST /example/_doc?refresh
{
    "name": "Wind & Wetter, Berlin, Germany",
    "location": {
        "type": "point",
        "coordinates": [13.400544, 52.530286]
    }
}
//查找这条记录
GET /example/_search
{
    "query":{
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "geo_shape": {
                    "location": {
                        "shape": {
                            "type": "envelope",
                            "coordinates" : [[13.0, 53.0], [14.0, 52.0]]
                        },
                        "relation": "within"
                    }
                }
            }
        }
    }
}

查询还支持使用已经在另一个索引和/或索引类型中建立索引的形状。当您有一个对应用程序有用的预定义形状列表,并且您希望使用逻辑名称(例如新西兰)引用它,而不是每次都必须提供它们的坐标时,这尤其有用。

//创建索引
PUT /shapes
{
    "mappings": {
        "_doc": {
            "properties": {
                "location": {
                    "type": "geo_shape"
                }
            }
        }
    }
}
//添加文档
PUT /shapes/_doc/deu
{
    "location": {
        "type": "envelope",
        "coordinates" : [[13.0, 53.0], [14.0, 52.0]]
    }
}
//Pre-indexed shape
GET /example/_search
{
    "query": {
        "bool": {
            "filter": {
                "geo_shape": {
                    "location": {
                        "indexed_shape": {
                            "index": "shapes",
                            "type": "_doc",
                            "id": "deu",
                            "path": "location"
                        }
                    }
                }
            }
        }
    }
}

指定检索

more_like_this query
此查询查找与指定的文本、文档或文档集合相似的文档
script query
这个查询允许脚本充当筛选器。还可以查看function_score查询
percolate query
此查询查找存储为与指定文档匹配的文档的查询
wrapper query
接受json或yaml字符串形式的其他查询的查询

跨度检索

span_term query
与术语查询等价,但用于其他span查询
span_multi query
包装术语、范围、前缀、通配符、regexp或模糊查询
span_first query
接受另一个span查询,该查询的匹配必须出现在字段的前N个位置中
span_near query
接受多个span查询,这些查询之间的匹配必须在指定的距离内,并且可能以相同的顺序
span_or query
组合多个span查询—返回匹配任何指定查询的文档
span_not query
包装另一个span查询,并排除与该查询匹配的任何文档
span_containing query
接受span查询的列表,但只返回与第二个span查询匹配的那些span
span_within query
如果单个span查询的结果属于其他span查询列表所返回的span,则返回该结果
field_masking_span query
允许类似span-near或span-或跨不同字段的查询

小结

ES 的中文文档是根据2.X版本翻译的,ES 的英文文档一个版本是没有更新到5.X版本,另一个已经更新。 
进行相关检索查询的时候,文档结构一篇一篇翻查,很零散、很不系统