ElasticSearch多索引和多类别搜索

通过限制搜索的不同索引或类型,我们可以在集群中跨 所有文档搜索。Elasticsearch转发搜索请求到集群中平行的主分片或每个分片的复制分片上,收集结果后选择顶部十个返回给我们。

通常,我们可能想搜索一个或几个自定的索引或类型,我们能通过定义URL中的索引或类型达到这个目的,像这样:

URL/_search      在所有索引的所有类型中搜索

URL/megacorp/_search       在索引megacorp的所有类型中搜索

URL/megacorp,zhttest/_search      在索引megacorp和zhttest下的所有类型中搜索

URL/m*,z*/_search       在以m和z开头的索引中,对其所有的类型进行搜索

URL/megacorp/employee/_search       在索引为megacorp,类型为employee下进行搜索

URL/megacorp,zhttest/employee,user/_search   在索引megacorp和zhttest下的employee和user类型下进行搜索;

URL/_all/employee,user/_search      在所有的索引下的employee和user类型进行搜索

当你搜索包含单一索引时,Elasticsearch转发搜索请求到这个索引的主分片或每个分片的复制分片上,然后聚集每个分片的结果。搜索包含多个索引也是同样的方式——只不过或有更多的分片被关联。

注:搜索一个索引有5个主分片和5个索引各有一个分片 事实上是一样的。

《空搜索》中我们看到172.16.7.2节点上显示在集群中有17个文档匹配我们的(空)搜索语句。单数只有10个文档在 hits 数组中。我们如何看到其他文档?

分页

Elasticsearch接受 from 和 size 参数:

size:每页显示结果数,默认10;

from:从第几页开始(跳过多少页),默认0;

例如:每页显示3个结果,从第3页开始

ElasticSearch多索引和多类别搜索

应该当心分页太深或者一次请求太多的结果。结果在返回前会被排序。但是记住一个搜索请求常常涉及多个分片。每个分片生成自己排好序的结果,它们接着需要集中起来排序以确保整体排序正确。

为了理解为什么深度分页是有问题的,让我们假设在一个有5个主分片的索引中搜索。当我们请求结果的第一页(结果1到10)时,每个分片产生自己最顶端10个结果然后返回它们给 请求节点(requesting node),它再排序这所有的50个结果以选出顶端的10个结果。

现在假设我们请求第1000页——结果10001到10010。工作方式都相同,不同的是每个分片都必须产生顶端的10010个结果。然后请求节点排序这50050个结果并丢弃50040个!

你可以看到在分布式系统中,排序结果的花费随着分页的深入而成倍增长。这也是为什么网络搜索引擎中任何语句不能返回多于1000个结果的原因。

简易搜索

search API有两种表单:一种是“简易版”的 查询字符串(query string)将所有参数通过查询字符串定义,另一种版本使用JSON完整的表示 请求体(request body),这种富搜索语言叫做结构化查询语句(DSL)。

简易搜索即查询字符串,例如要查询所有类型为employee,且字段sex中包含woman字符的文档:

ElasticSearch多索引和多类别搜索

再如:查询查询所有类型为employee,且字段last_name为Zhang,first_name中以H开头的所有结果:

ElasticSearch多索引和多类别搜索

看下个查询语句:将first_name前的“+”改为“-”,则查询结果却完全不一样了:

ElasticSearch多索引和多类别搜索

"+" 前缀表示语句匹配条件 必须被满足。类似的 "-" 前缀表示条件 必须不被满足。所有条件如果没有 + 或 - 表示是可选的——匹配越多,相关的文档就越多。

内置字段_all

上边了解了简易搜索的方式和用法,那么ElasticSearch是如何找到不同字段的结果的?

当你索引一个文档,Elasticsearch把所有字符串字段值连接起来放在一个大字符串中,它被索引为一个特殊的字段 _all 。例如要索引的文档如下:

{

    "last_name":"Zhang"

    "first_name":"Haitao"

    "age":27

    "about":"I like my wife!"

}

这好比我们增加了一个叫做 _all 的额外字段值:

"Zhang Haitao 27 I like my wife!"

查询字符串在查询时,先通过 _all 字段搜索,其后锁定其他字符串。

查询字符串搜索允许任意用户在索引中任何一个字段上运行潜在的慢查询语句,可能暴露私有信息甚至使你的集群瘫痪。因为这些原因,我们不建议直接暴露查询字符串搜索给用户,除非这些用户对于你的数据和集群可信。

取而代之的,生产环境我们一般依赖全功能的 请求体搜索API,它能完成前面所有的事情,甚至更多。在了解它们之前,我们首先需要看看数据是如何在Elasticsearch中被索引的。

在ElasticSearch中的查询,如果指定了确切的匹配字段,则查询的为确切值,如果没有指定确切的字段,则查询按照String类型的_all字段查询。所以可能会导致查询的结果不一样;