一些查询字符串(query-string)可选参数能够影响搜索过程。preference(偏爱)preference参数允许你控制使用哪个分片或节点来处理搜索请求。她接受如下一些参数 _primary, _primary_first, _local, _only_node:xyz, _prefer_node:xyz和_shards:2,3。这些参数在文档搜索偏好(search preference)里有详细描述。
查询阶段辨别出那些满足搜索请求的document,但我们仍然需要取回那些document本身。这就是取回阶段的工作,如图分布式搜索的取回阶段所示。图2 分布式搜索取回阶段分发阶段由以下步骤构成:1.协调节点辨别出哪个document需要取回,并且向相关分片发出GET请求。2.每个分片加载document并且根据需要_丰富(enrich)_它们,然后再将document返回协调节点。3.
在初始化查询阶段(query phase),查询被向索引中的每个分片副本(原本或副本)广播。每个分片在本地执行搜索并且建立了匹配document的优先队列(priority queue)。优先队列一个优先队列(priority queue is)只是一个存有前n个(top-n)匹配document的有序列表。这个优先队列的大小由分页参数from和size决定。
在继续之前,我们将绕道讲一下搜索是如何在分布式环境中执行的。 它比我们之前讲的基础的增删改查(create-read-update-delete ,CRUD)请求要复杂一些。注意:本章的信息只是出于兴趣阅读,使用Elasticsearch并不需要理解和记住这里的所有细节。阅读这一章只是增加对系统如何工作的了解,并让你知道这些信息以备以后参考,所以别淹没在细节里。
本章的目的在于介绍关于ElasticSearch内部的一些运行情况。在这里我们先不介绍新的知识点,数据字段是我们要经常查阅的内容之一,但我们使用的时候不必太在意。当你对一个字段进行排序时,ElasticSearch 需要进入每个匹配到的文档得到相关的值。倒排索引在用于搜索时是非常卓越的,但却不是理想的排序结构。当搜索的时候,我们需要用检索词去遍历所有的文档。
我们曾经讲过,默认情况下,返回结果是按相关性倒序排列的。但是什么是相关性? 相关性如何计算?每个文档都有相关性评分,用一个相对的浮点数字段 _score 来表示 -- _score 的评分越高,相关性越高。查询语句会为每个文档添加一个 _score 字段。
译者注: 多值字段是指同一个字段在ES索引中可以有多个含义,即可使用多个分析器(analyser)进行分词与排序,也可以不添加分析器,保留原值。被分析器(analyser)处理过的字符称为analyzed field(译者注:即已被分词并排序的字段,所有写入ES中的字段默认圴会被analyzed), analyzed字符串字段同时也是多值字段,在这些字段上排序往往得不到你想要的值。
默认情况下,结果集会按照相关性进行排序 -- 相关性越高,排名越靠前。这一章我们会讲述相关性是什么以及它是如何计算的。在此之前,我们先看一下sort参数的使用方法。排序方式为了使结果可以按照相关性进行排序,我们需要一个相关性的值。在ElasticSearch的查询结果中,相关性分值会用_score字段来给出一个浮点型的数值,所以默认情况下,结果集以_score进行倒序排列。
这一章详细介绍了如何在项目中使用常见的查询语句。也就是说,想要完全掌握搜索和结构化查询,还需要在工作中花费大量的时间来理解ES的工作方式。更高级的部分,我们将会在《深入搜索》中详细讲解,但是在讲解之前,你还需要理解查询结果是如何进行排序的,下一章我们将学习如何根据相关性对查询结果进行排序以及指定排序过程。
查询语句可以变得非常复杂,特别是与不同的分析器和字段映射相结合后,就会有些难度。validate API 可以验证一条查询语句是否合法。
查询语句和过滤语句可以放在各自的上下文中。在 ElasticSearch API 中我们会看到许多带有 query 或 filter 的语句。这些语句既可以包含单条 query 语句,也可以包含一条 filter 子句。换句话说,这些语句需要首先创建一个query或filter的上下文关系。复合查询语句可以加入其他查询子句,复合过滤语句也可以加入其他过滤子句。
Elasticsearch 提供了丰富的查询过滤语句,而有一些是我们较常用到的。我们将会在后续的《深入搜索》中展开讨论,现在我们快速的介绍一下这些最常用到的查询过滤语句。
前面我们讲到的是关于结构化查询语句,事实上我们可以使用两种结构化语句:结构化查询(Query DSL)和结构化过滤(Filter DSL)。查询与过滤语句非常相似,但是它们由于使用目的不同而稍有差异。一条过滤语句会询问每个文档的字段值是否包含着特定值:created 的日期范围是否在 2013 到 2014 ?status 字段中是否包含单词 "published" ?
结构化查询是一种灵活的,多表现形式的查询语言。Elasticsearch在一个简单的JSON接口中用结构化查询来展现Lucene绝大多数能力。你应当在你的产品中采用这种方式进行查询。它使得你的查询更加灵活,精准,易于阅读并且易于debug。
简单查询语句(lite)是一种有效的命令行_adhoc_查询。但是,如果你想要善用搜索,你必须使用请求体查询(request body search)API。之所以这么称呼,是因为大多数的参数以JSON格式所容纳而非查询字符串。请求体查询(下文简称查询),并不仅仅用来处理查询,而且还可以高亮返回结果中的片段,并且给出帮助你的用户找寻最好结果的相关数据建议。
除了之前提到的简单的标量类型,JSON还有null值,数组和对象,所有这些Elasticsearch都支持:多值字段我们想让tag字段包含多个字段,这非常有可能发生。我们可以索引一个标签数组来代替单一字符串:{ "tag": [ "search", "nosql" ]}对于数组不需要特殊的映射。任何一个字段可以包含零个、一个或多个值,同样对于全文字段将被分析并产生多个词。
为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成全文本(Full-text)或精确的字符串值,Elasticsearch需要知道每个字段里面都包含了什么类型。这些类型和字段的信息存储(包含)在映射(mapping)中。正如《数据吞吐》一节所说,索引中每个文档都有一个类型(type)。每个类型拥有自己的映射(mapping)或者模式定义(schema definition)。
分析(analysis)是这样一个过程:首先,标记化一个文本块为适用于倒排索引单独的词(term)然后标准化这些词为标准形式,提高它们的“可搜索性”或“查全率”这个工作是分析器(analyzer)完成的。一个分析器(analyzer)只是一个包装用于将三个功能放到一个包里:字符过滤器首先字符串经过字符过滤器(character filter),它们的工作是在标记化前处理字符串。
关注时代Java