ELK STACK之elasticsearch(二)数据搜索

ELK STACK ginotang 679℃ 0评论

在elasticsearch中搜索数据

保存数据是为了以后可以方便查询,ES提供了强大的搜索API,配合查询表达式,让ES的数据搜索更加简单

search API

_search API提供易用且强大的搜索接口,让数据查询变得简单。

  • 查询数据库中的所有数据:

如果不指定Index,那么_search会返回所有Index中的数据

  • 查询指定Index中的数据

假如数据库中存在名为bank的Index,那么下面的查询会返回所有bank中的数据

很明显,_search放置于哪一个Index下面,就返回该Index的数据。

  • 多Index查询

假如存在名为megacorp和bank的索引,下面的查询会同时返回两个索引下的数据

多个索引使用逗号(,)分隔,索引名称还可以使用通配符(*),例如

查询表达式

_search API 配合查询表达式使用,可以对返回的数据进行模糊匹配或者精确匹配。查询表达式作为请求体发送给ES。模糊查询使用match查询,而精确查询使用term查询。

match_all查询

match_all是最简单的查询表达式, 它匹配所有数据:

具体使用方法

当然,match_all是最没用的查询条件,它返回的结果和不用查询表达式一样,都是返回全部的数据。

match查询

match只返回和给定条件匹配的数据

上面的查询条件可能会令人产生怀疑:因为只要about字段中含有rock和climbing两者之一,该数据就会被返回,而不是两者同时存在才被返回。

match_phrase查询

短语匹配,如果要多个短语同时存在才返回数据,那么就需要使用match_phrase查询。下面的查询返回含有rock climbing短语的数据,且只有它们两者同时存在才返回

match_phrase也可以用另一种方式编写

multi_match查询

无论是match还是match_phrase,它们都只能针对一个字段进行搜索,如果要从多个字段中进行数据搜索,就要使用multi_match。

上面的查询在employercity中搜索内容Bennett,只要两个字段其中之一匹配到数据,即可返回。

term/terms查询

这两个查询用于精确查询,查询的值通常是数字、时间和布尔值。

注意:如果对文本类型的字段值不作特殊处理(特殊处理是把把字符串值标记为not_analyzed),那么term/terms查询对这些文本值无效

我们可以更新一个映射来添加一个新域,但不能将一个存在的域从 analyzed 改为 not_analyzed,如果一个域的映射已经存在,那么该域的数据可能已经被索引。如果你意图修改这个域的映射,索引的数据可能会出错,不能被正常的搜索

not_analyzed只能在5.0之前的版本中使用,新版本中已经使用keyword代替。

例如,旧版本:

新版本则是:

term用于对单一值进行查询:

返回bank索引中年龄为20的客户

terms是term的复数形式,因此terms查询可以提交多个值:

下面的查询返回bank索引中年龄为20和30的客户

range查询

range用于查找某个范围内的数据,例如查找bank索引中年龄介于20~30之间的客户资料

组合多查询

elasticsearch允许组合多个条件进行查询,这是通过bool查询来实现的,bool查询接收以下参数:

  • must 返回的文档必须匹配这些条件
  • must_not 返回的文档必须不匹配这些条件
  • should 对返回的结果增加_score,用于修正文档的相关性得分
  • filter 返回的文档必须匹配条件

下面的查询用于查找 title 字段匹配 how to make millions 并且不被标识为 spam 的文档。那些被标识为 starred 或在2014之后的文档,将比另外那些文档拥有更高的排名。如果 两者 都满足,那么它排名将更高:

过滤器

如果我们不想因为文档的时间而影响得分,可以用 filter 语句来重写前面的例子:

通过将 range 查询移到 filter 语句中,我们将它转成不评分的查询,将不再影响文档的相关性排名。由于它现在是一个不评分的查询,可以使用各种对 filter 查询有效的优化手段来提升性能。

如果你需要通过多个不同的标准来过滤你的文档,bool 查询本身也可以被用做不评分的查询。简单地将它放置到 filter 语句中并在内部构建布尔逻辑:

可以看到,filter和term查询一样,作用域基本上是数字、时间和布尔值,还有那些被标记为not_analyzed的字段

过滤器并非必须和must、must_not、should等一起使用,也可以单独使用:

constant_score查询和过滤器

constant_score用于把一个评分查询转换为非评分查询,constant_score下必须包含filter。

使用boost提升权重

我们可以通过指定 boost 来控制任何查询语句的相对的权重, boost 的默认值为 1 ,大于 1 会提升一个语句的相对权重。

查询(query)和过滤(filtering)

查询和过滤的相同之处在于,它们都会对数据进行匹配。不同的是,查询会对结果产生一个匹配程度,可以通过结果中的_score字段查看这个值;过滤则只有匹配和不匹配,没有权重的概念。

除此之外,它们之间的性能会有一定的差距,以下内容摘自官方文档

过滤查询(Filtering queries)只是简单的检查包含或者排除,这就使得计算起来非常快。考虑到至少有一个过滤查询(filtering query)的结果是 “稀少的”(很少匹配的文档),并且经常使用不评分查询(non-scoring queries),结果会被缓存到内存中以便快速读取,所以有各种各样的手段来优化查询结果。

相反,评分查询(scoring queries)不仅仅要找出 匹配的文档,还要计算每个匹配文档的相关性,计算相关性使得它们比不评分查询费力的多。同时,查询结果并不缓存。

多亏倒排索引(inverted index),一个简单的评分查询在匹配少量文档时可能与一个涵盖百万文档的filter表现的一样好,甚至会更好。但是在一般情况下,一个filter 会比一个评分的query性能更优异,并且每次都表现的很稳定。

过滤(filtering)的目标是减少那些需要通过评分查询(scoring queries)进行检查的文档。

查询和过滤的选择

下面的内容同样摘自官方文档

通常的规则是,使用 查询(query)语句来进行 全文 搜索或者其它任何需要影响 相关性得分 的搜索。除此以外的情况都使用过滤(filters)。

查询通常都是对结果的模糊匹配,过滤的目的是对查询返回的结果进行更精确的筛选。

举个例子:当我们使用搜索引擎的时候,会输入特定的关键字,然后搜索引擎会根据相关性返回结果,这些返回的结果中我们可以根据需要选择搜索类型是图片、视频还是新闻等等,后面这个过程就类似过滤。

转载请注明:Pure nonsense » ELK STACK之elasticsearch(二)数据搜索

喜欢 (0)
0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x
()
x