1 查询Elasticsearch
如果想发送的不是一个简单的查询,仍然把它封装为JSON结构并发送给Elasticsearch。
这就是所谓的查询DSL。
Elasticsearch支持两种类型的查询:基本查询和复合查询, 过滤查询。
基本查询,如词条查询用于查询实际数据。
复合查询,如布尔查询,可以合并多个查询。
过滤查询,根据一定的条件缩小查询结果。不像其他查询,筛选查询不会影响得分,而且通常非常高效
示例数据:
简单查询:
为了搜索title字段中的crime一词,使用下面的命令:
如果从Elasticsearch的查询DSL的视点来看,上面的查询
是一种query_string查询,它查询title字段中含有crime一词的文档,可以这样写:
{
"query" : {
"query_string" : { "query" : "title:crime" }
}
}
分页和结果集:
from:该属性指定我们希望在结果中返回的起始文档。它的默认值是0,表示想要得到从
第一个文档开始的结果。
size:该属性指定了一次查询中返回的最大文档数,默认值为10。如果只对切面结果感
兴趣,并不关心文档本身,可以把这个参数设置成0。
{
"from" : 9,
"size" : 20,
"query" : {
"query_string" : { "query" : "title:crime" }
}
}
返回版本值:(设置返回版本)
{
"version" : true,
"query" : {
"query_string" : {
"query" : "title:crime"
}
}
}
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.15342641,
"hits" : [ {
"_index" : "library",
"_type" : "book",
"_id" : "4",
"_version" : 1,
"_score" : 0.15342641,
"_source" : {
"title": "Crime and Punishment",
"otitle": "ПреступлéнXие и наказáние",
"author": "Fyodor Dostoevsky","year": 1886,
"characters": ["Raskolnikov", "Sofia SemyonoMarmeladova"],
"tags": [],
"copies": 0,
"available" : true
}
}]
}
}
限制得分:
Elasticsearch提供一项功能,让我们可以根据文档需要满足的最低得分值,
来过滤结果。为了用此功能,必须在JSON顶层提供min_score属性和最低得分值。如,希望
我们的查询只返回得分高于0.75的文档,发出以下查询(查询增加min_score)
选择需要的返回值:
只能返回那些在用于创建索引的映射中标记为存储的字段,或者你使用了_source字段
(Elasticsearch使用_source字段提供存储字段)。因此,要让每个结果中的文档
只返回title和year字段,发送下面的查询到Elasticsearch:
1 (增加"fields" : [ "title", "year" ]这样的查询规则)
如果没有定义fields数组,它将用默认值,如果有就返回_source字段;
如果使用_source字段,并且请求一个没有存储的字段,那么这个字段将从_source字
段中提取(然而,这需要额外的处理);
如果想返回所有的存储字段,只需传入星号(*)作为字段名字。
从性能的角度,返回_source字段比返回多个存储字段更好。
2 通过include和exclude排除部分字段
{
"partial_fields" : {
"partial1" : {
"include" : [ "titl*" ],
"exclude" : [ "chara*" ]
}
},
"query" : {
"query_string" : { "query" : "title:crime" }
}
}
使用脚本字段:(跳过)
2 理解查询过程
要知道在大多数情况下,Elasticsearch需要分散查询到多个节点中,得到结果,合并它们,
再获取有关文档并返回结果。我们还没谈到的是另外三个定义查询行为的东西:
查询重写
搜索类型
查询执行
查询逻辑:
Elasticsearch是一个分布式搜索引擎,因此提供的所有功能在性质上都必须是分布式的
查询发送到Elasticsearch的其中一个节点,这时发生的是一个所谓的发散阶段。查询分布到
建立过索引的所有分片上。如果它建立在5个分片和1个副本基础上,那么,这5个实体分片都会
被查询(不需要同时查询分片及其副本,因为它们包含相同的数据)。每个查询的分片将只返回
文档的标识符和得分。发送分散查询的节点将等待所有的分片完成它们的任务,收集结果并适当
排序(在这种情况下,按得分从低到高)。
之后,将发送一个新的请求来生成搜索结果。然而,这次请求将只发送到那些持有响应所需
文档的分片上。在大多数情况下, Elasticsearch不会把请求发送到所有的分片,而只是发送给其
中的一部分。这是因为通常不需要整个查询结果,只要一部分。这一阶段被称为收集阶段(gather
phase)。收集完所有文档,将建立最终响应,并返回查询结果。
搜索类型
Elasticsearch允许通过指定搜索类型来选择查询在内部如何处理。不同的搜索类型适合不同
的情况;可以只在乎性能,但有时查询的关联性可能是最重要的因素。你应该记得每个分片是一
个小的Lucene索引,为了返回更多相关的结果,频率等信息需要在分片之间传输。为了控制查询
如何执行,可以使用search_type请求参数,并将其设置为下列值之一。
query_then_fetch:
第一步,执行查询得到对文档进行排序和分级所需信息。这一步
在所有的分片上执行。然后,只在相关分片上查询文档的实际内容。
此查询类型返回结果的最大数量等于size参数的值。如果没有指定搜索类型,就默认使用这个类型。
query_and_fetch:
这通常是最快也最简单的搜索类型实现。查询在所有分片上并行执行
(当然,任意一个主分片,只查询一个副本),所有分片返回等于size值的结果数。返
回文档的最大数量等于size的值乘以分片的数量。
dfs_query_and_fetch:
这个跟query_and_fetch类似,它包含一个额外阶段,在初始查询中执行分布式词频的计算,
以得到返回文件的更精确的得分,从而让查询结果更相关
dfs_query_then_fetch:
但比query_ then_fetch多了一个额外的阶段,就像dfs_query_and_fetch一样。
count:这是一个特殊的搜索,只返回匹配查询的文档数。如果你只需要结果数量,
而不关心文档,应该使用这个搜索类型。
scan:
这是另一个特殊的搜索类型,只有在要让查询返回大量结果时才用。它跟一般的
查询有点不同,因为在发送第一个请求之后, Elasticsearch响应一个滚动标识符,类似于
关系型数据库中的游标
搜索执行偏好
除了可以控制查询是如何执行的,也可以控制在哪些分片上执行查询。默认情况下,
Elasticsearch使用的分片和副本,既包含我们已经发送过请求的可用节点,
又包括集群中的其他节点在大多数情况下,默认行为是最佳的查询首选方法。
有时我们要更改默认行为.如,可能希望只在主分片上执行搜索。为此,可以设置偏好请求参数
搜索分片
在讨论搜索偏好时,还想提到Elasticsearch所公开的搜索分片API。此API允许检查将执行查
询的分片。需要在_search_shards REST端点执行这个API。若要查看查询如何执行,运行以
下命令(_search_shards ):curl -XGET 'localhost:9200/library/_search_shards?pretty' -d
'{"query":"match_all":{}}'
3 基本查询
词条查询:
{
"query" : {
"term" : {
"title" : "crime"
}
}
}
多词条查询:
{
"query" : {
"terms" : {
"tags" : [ "novel", "book" ],
"minimum_match" : 1
}
}
}
match_all查询:
{
"query" : {
"match_all" : {
"boost" : 2.0
}
}
}
常用词查询:
{
"query" : {
"common" : {
"title" : {
"query" : "crime and punishment",
"cutoff_frequency" : 0.001
}
}
}
}
query:这个参数定义了实际的查询内容。
cutoff_frequency: 这个参数定义一个百分比(0.001表示0.1%)或一个绝对值(当此
属性值>=1时)。这个值用来构建高、低频词组。此参数设置为0.001意味着频率<=0.1%的
词将出现在低频词组中。
low_freq_operator:这个参数可以设为or或and,默认是or。它用来指定为低频词组
构建查询时用到的布尔运算符。如果希望所有的词都在文档中出现才认为是匹配,应该
把它设置为and。
high_freq_operator:这个参数可以设为or或and,默认是o。它用来指定为高频词组
构建查询时用到的布尔运算符。如果希望所有的词都在文档中出现才认为是匹配,那么
应该把它设置为and。
minimum_should_match:不使用low_freq_operator和high_freq_operator参数
的话,可以使用minimum_should_match参数。和其他查询一样,它允许指定匹配的文
档中应该出现的查询词的最小个数。
boost:这个参数定义了赋给文档得分的加权值。
analyzer:这个参数定义了分析查询文本时用到的分析器名称。默认值为default
analyzer。
disable_coord:此参数的值默认为false,它允许启用或禁用分数因子的计算,该计
算基于文档中包含的所有查询词的分数。把它设置为true,得分不那么精确,但查询将
稍快。
match查询:
{
"query" : {
"match" : {
"title" : "crime and punishment"
}
}
}
布尔值匹配查询
operator:此参数可以接受or和and,控制用来连接创建的布尔条件的布尔运算符。默
认值是or。如果希望查询中的所有条件都匹配,可以使用and运算符。
analyzer:这个参数定义了分析查询文本时用到的分析器的名字。默认值为default
analyzer。
fuzziness:可以通过提供此参数的值来构建模糊查询(fuzzy query)。它为字符串类型
提供从0.0到1.0的值。构造模糊查询时,该参数将用来设置相似性。
prefix_length:此参数可以控制模糊查询的行为。
max_expansions:此参数可以控制模糊查询的行为。
zero_terms_query:该参数允许指定当所有的词条都被分析器移除时(例如,因为停
止词),查询的行为。它可以被设置为none或all,默认值是none。在分析器移除所有查
询词条时,该参数设置为none,将没有文档返回;设置为all,则将返回所有文档。
cutoff_frequency:该参数允许将查询分解成两组:一组低频词和一组高频词。
match_phrase查询
slop:这是一个整数值,该值定义了文本查询中的词条和词条之间可以有多少个未知词
条,以被视为跟一个短语匹配。此参数的默认值是0,意味着,不允许有额外的词条。
analyzer:这个参数定义了分析查询文本时的分析器的。默认值为default analyzer。
match_phrase_prefix查询
此查询跟match_phrase查询几乎一样,但除此之外,
它允许查询文本的最后一个词条只做前缀匹配。
此外,除了match_phrase查询公开的参数,还公开了一个额外参数max_expansions。
这个参数控制有多少前缀将被重写成最后的词条。
我们的示例查询若改用match_phrase前缀来写
{
"query" : {
"match_phrase_prefix" : {
"title" : {
"query" : "crime and punishm",
"slop" : 1,
"max_expansions" : 20
}
}
}
}
multi_match查询:
multi_match查询和match查询一样,不同的是它不是针对单个字段,而是可以通过
fields参数针对多个字段查询。
{
"query" : {
"multi_match" : {
"query" : "crime punishment",
"fields" : [ "title", "otitle" ]
}
}
}
use_dis_max:该参数定义一个布尔值,设置为true时,使用析取最大分查询,设置为
false时,使用布尔查询。默认值为true。 3.3.18节将讨论更多细节。
tie_breaker:只有在use_dis_max参数设为true时才会使用这个参数。它指定低分数
项和最高分数项之间的平衡。 3.3.18节将介绍更多细节。
query_string查询:
simple_query_string 查询:
标识符查询:
{
"query" : {
"ids" : {
"type" : "book",
"values" : [ "10", "11", "12", "13" ]
}
}
}
前缀查询:
{
"query" : {
"prefix" : {
"title" : {
"value" : "cri",
"boost" : 3.0
}
}
}
}
fuzzy_like_this 查询:
{
"query": {
"fuzzy_like_this": {
"fields": ["title", "otitle"],
"like_text": "crime punishment"
}
}
}
fuzzy_like_this查询支持以下查询参数。
fields:此参数定义应该执行查询的字段数组,默认值是_all字段。
like_text:这是一个必需参数,包含用来跟文档比较的文本。
ignore_tf:此参数指定在相似度计算期间,是否应忽略词频,默认值为false,意味
着将使用词频。
max_query_terms:此参数指定生成的查询中能包括的最大查询词条数,默认值为25。
min_similarity:此参数指定差分词条(differencing terms)应该有的最小相似性,默
认值为0.5。
prefix_length:此参数指定差分词条的公共前缀长度,默认值为0。
boost:此参数指定使用的加权值,默认值为1.0。
analyzer:这个参数定义了分析所提供文本时用到的分析器名称。
fuzzy_like_this_field 查询:
fuzzy_like_this_field查询和fuzzy_like_this查询类似,但它只能对应单个字段。
正因为如此,它不支持多字段属性。
{
"query": {
"fuzzy_like_this_field": {
"title": {
"like_text": "crime and punishment"
}
}
}
}
fuzzy 查询(此查询很占用CPU资源):
{
"query": {
"fuzzy": {
"title": "crme"
}
}
}
value:此参数指定了实际的查询。
boost:此参数指定了查询的加权值,默认为1.0。
min_similarity:此参数指定了一个词条被算作匹配所必须拥有的最小相似度。对字
符串字段来说,这个值应该在0到1之间,包含0和1。对于数值型字段,这个值可以大于1,
比如查询值是20, min_similarity设为3,则可以得到17~23的值。对于日期字段,可
以把min_similarity参数值设为1d、 2d、 1m等,分别表示1天、 2天、 1个月。
prefix_length:此参数指定差分词条的公共前缀长度,默认值为0。
max_expansions:此参数指定查询可被扩展到的最大词条数,默认值是无限制。
通配符查询(通配符查询允许我们在查询值中使用*和?等通配符):
{
"query" : {
"wildcard" : {
"title" : {
"value" : "cr?me",
"boost" : 20.0
}
}
}
}
more_like_this 查询:
{
"query" : {
"more_like_this" : {
"fields" : [ "title", "otitle" ],
"like_text" : "crime and punishment",
"min_term_freq" : 1,
"min_doc_freq" : 1
}
}
}
more_like_this_filed 查询:
more_like_this_field查询与more_like_this查询类似,但它只能针对单个字段。正
因为如此,它不支持多字段属性。
{
"query" : {
"more_like_this_field" : {
"title" : {
"like_text" : "crime and punishment",
"min_term_freq" : 1,
"min_doc_freq" : 1
}
}
}
}
范围查询:
{
"query" : {
"range" : {
"year" : {
"gte" : 1700,
"lte" : 1900
}
}
}
}
最大分查询:
最大分查询非常有用,因为它会生成一个由所有子查询返回的文档组成的并集并将它返回
我们可以控制较低得分的子查询对文档最后得分的影响
文档的最后得分是这样计算的:最高分数的子查询的得分之和,
加上其余子查询的得分之和乘以tie参数的值。
所以,可以通过tie_breaker参数来控制较低得分的查询对最后得分的影响。
把tie_breaker设为1.0,得到确切的总和;把tie_breaker设为0.1,结果,除最高得分的查
询外,只有所有查询总得分的10%被加到最后得分里
{
"query": {
"dismax": {
"tie_breaker": 0.99,
"boost": 10.0,
"queries": [{
"match": {
"title": "crime"
}
},
{
"match": {
"author": "fyodor"
}
}
]
}
}
}
正则表达式查询:
{
"query": {
"regexp": {
"title": {
"value": "cr.m[ae]",
"boost": 10.0
}
}
}
}
4 复合查询
布尔查询
should:被它封装的布尔查询可能被匹配,也可能不被匹配。被匹配的should节点数目
由minimum_should_match参数控制。
must:被它封装的布尔查询必须被匹配,文档才会返回。
must_not:被它封装的布尔查询必须不被匹配,文档才会返回。
上述每个节点都可以在单个布尔查询中出现多次。这允许建立非常复杂的查询,有多个嵌套
级别(在一个布尔查询中包含另一个布尔查询)。记住,结果文档的得分将由文档匹配的所有封
装的查询得分总和计算得到。
除了上述部分以外,还可以在查询主体中添加以下参数控制其行为。
boost:此参数指定了查询使用的加权值,默认为1.0。加权值越高,匹配文档的得分越高。
minimum_should_match:此参数的值描述了文档被视为匹配时,应该匹配的should
子句的最少数量。举例来说,它可以是个整数值,比如2,也可以是个百分比
disable_coord:此参数的默认值为false,允许启用或禁用分数因子的计算,该计算
是基于文档包含的所有查询词条。如果得分不必太精确,但要查询快点,那么应该将它设置为true。
{
"query": {
"bool": {
"must": {
"term": {
"title": "crime"
}
},
"should": {
"range": {
"year": {
"from": 1900,
"to": 2000
}
}
},
"must_not": {
"term": {
"otitle": "nothing"
}
}
}
}
}
加权查询:
加权查询的优点是, positive部分和negative部分包含的查询结果都会出现在搜索结果
中,而某些查询的得分将被降低。如果使用布尔查询的must_not节点,将得不到这样的结果。
假设我们想要一个简单的词条查询,查询title字段中含有crime词条,希望这样的文档得
分不被改变,同时要year字段在1800~1900内的文档,但这样文档的得分要有一个0.5的加权。这
样的查询如下所示:
{
"query": {
"boosting": {
"positive": {
"term": {
"title": "crime"
}
},
"negative": {
"range": {
"year": {
"from": 1800,
"to": 1900
}
}
},
"negative_boost": 0.5
}
}
}
constant_score 查询
如果希望
title字段包含crime词条的所有文档的得分为2.0,
{
"query": {
"constant_score": {
"query": {
"term": {
"title": "crime"
}
},
"boost": 2.0
}
}
}
索引查询
{
"query": {
"indices": {
"indices": ["library"],
"query": {
"term": {
"title": "crime"
}
},
"no_match_query": {
"term": {
"user": "crime"
}
}
}
}
}
上述查询中, query属性中的查询将执行在library索引上, no_match_query属性中的查
询将执行在集群中其他所有索引上。
no_match_query属性也可以是个字符串值,而不是一个查询。这个字符串值可以是all或
者none,默认是all。设置为all,索引中不匹配的所有文档都会返回;设置为none,索引中不
匹配的文档将不会返回。
5 查询结果的过滤
使用过滤器:
以下有关过滤器的章节中,我们使用post_filter参数保持例子尽可能地简单。然而,请记住,
如果可能,应该总是使用filtered查询,而不是post_filter,因为filtered执行起来更快。
过滤器不影响评分,而得分计算让搜索变得复杂,而且需要CPU资源。
另一方面,过滤是一种相对简单的操作。由于过滤应用在整个索引的内容上,过滤
的结果独立于找到的文档,也独立于文档之间的关系。过滤器很容易被缓存,从而进一步提高过
滤查询的整体性能(它返回给定title的所有文档,但结果缩小到仅在1961年出版的书)该过滤方式
过滤发生在在运行查询之前,
性能更好
{
"query": {
"filtered": {
"query": {
"match": {
"title": "Catch-22"
}
},
"filter": {
"term": {
"year": 1961
}
}
}
}
}
过滤器类型
1. 范围过滤器
{
"post_filter": {
"range": {
"year": {
"gte": 1930,
"lte": 1990
}
}
}
}
2. exists过滤器
exists过滤器非常简单。它过滤掉给定字段上没有值的文档。
{
"post_filter" : {
"exists" : { "field": "year" }
}
}
上述过滤器将只返回year字段有值的文档。
3. missing过滤器
{
"post_filter" : {
"missing" : {
"field": "year",
"null_value": 0,
"existence": true
}
}
}
4. 脚本过滤器(暂不care)
5. 类型过滤器
类型过滤器专门用来限制文档的类型。当查询运行在多个索引上,或单个索引但有很多类型
时,可以使用这个过滤器。例如,想限制返回文档的类型为book,使用下列过滤器:
{
"post_filter" : {
"type": {
"value" : "book"
}
}
}
6. 限定过滤器
限定过滤器限定单个分片返回的文档数目。不要把它跟size参数混在一起。作为例子,我
们看看下面的过滤器:
{
"post_filter" : {
"limit" : {
"value" : 1
}
}
}
7. 标识符过滤器
需要过滤成若干具体的文档时,可以使用标识符过滤器。例如,要排除标识符等于1的文档,
可使用类似下面的代码:
{
"post_filter": {
"ids" : {
"type": ["book"],
"values": [1]
}
}
}
9. 组合过滤器
现在,是时候把一些过滤器组合在一起了。第一个选择是使用bool过滤器。
第二种选择是使用and、 or和not过滤器。 and过滤器使用一个过滤器数组并返回与该数组中的所有过滤器匹配的文档。or过滤器也使用一个数组,但它返回与数组中任何一个过滤器匹配的文档。
至于not过滤器,则返回与所封装的过滤器不匹配的文档。
当然,所有这些过滤器可以嵌套使用,如以下示例所示
{
"post_filter": {
"not": {
"and": [{
"term": {
"title": "Catch-22"
}
},
{
"or": [{
"range": {
"year": {
"gte": 1930,
"lte": 1990
}
}
},
{
"term": {
"available": true
}
}
]
}
]
}
}
}
10. 命名过滤器
设置过滤器可能很复杂,所以有时候,如果知道哪些过滤器用来决定查询应该返回哪些文档,
无疑是很有帮助的。幸好,可以给每个过滤器命名,名字将随着匹配文档返回。来看看它是如何
工作的。以下查询将返回所有可用并且标签为novel,或者来自19世纪的书:
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"or": [{
"and": [{
"term": {
"available": true
}
},
{
"term": {
"tags": "novel"
}
}
]
},
{
"range": {
"year": {
"gte": 1800,
"lte": 1899
}
}
}
]
}
}
}
}
过滤器的缓存
缓存加速了使用过滤器的查询,代价是第一次执行过滤器
时的内存成本和查询时间。因此,缓存的最佳选择是那些可以重复使用的过滤器,例如,经常会
使用并包括参数值的那些。
缓存可以在and、bool、or过滤器上打开(但通常,缓存它们所附的过滤器才是更好的主意)。
在这种情况下,所需的语法与前面命名过滤器所描述的一样,如下所示:
{
"post_filter" : {
"script" : {
"_cache": true,
"script" : "now - doc['year'].value > 100",
"params" : {
"now" : 2012
}
}
}
}
6 高亮显示
高亮显示入门
{
"query": {
"term": {
"title": "crime"
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
字段配置
为了执行高亮显示,需要呈现字段的原始内容:我们必须把这些用来高亮显示的字段设为
stored,或者把这些字段包含在_source字段中
高亮优化设置
Elasticsearch在底层使用Apache Lucene,而高亮显示是Lucene库的功能之一。 Lucene提供了
三种类型的高亮实现:标准类型,就是我们刚刚使用的;第二种叫FastVectorHighlighter,
它需要词向量和位置才能工作;第三种叫PostingsHighlighter,本章的最后将讨论它。
Elasticsearch自动选择正确的高亮实现方式:如果字段的配置中, term_vector属性设成了
with_positions_offsets,则将使用FastVectorHighlighter。
然而,必须记住,使用词向量将导致索引变大,但高亮显示的执行需要更少的时间。此外,
对于存储了大量数据的字段来说,推荐使用FastVectorHighlighter
配置 HTML 标签
例如,假设要使用标准的HTML<b>标签来高亮。为此,
我们应分别设置pre_tags和post_tags这些属性(它们是数
组)为<b>和</b>。既然提到的两个属性为数组,可以包含多个标签,
Elasticsearch将使用定义的每个标签来高亮显示不同的单词。所以,我们的示例查询如下所示:
{
"query" : {
"term" : {
"title" : "crime"
}
},
"highlight" : {
"pre_tags" : [ "<b>" ],
"post_tags" : [ "</b>" ],
"fields" : {
"title" : {}
}
}
}
控制高亮片段
Elasticsearch允许我们控制高亮片段的数量以及它们的大小,为此公开了两个属性供使用。
第一个, number_of_fragments,定义Elasticsearch返回的片段数量,默认值为5。把这个属性
设置为0,将导致整个字段被返回,这对短字段来说是很便利的;然而,对长字段来说代价较大。
第二个属性是fragment_size,用来指定高亮片段的最大字符长度,默认值是100。
全局设置与局部设置
前面讨论的高亮显示的属性,可以设在全局范围,也可以设在每个字段上。全局设置将用在
没有做局部设置的所有字段上,它跟高亮对象的fields节点设在同一个级别上,如下所示
全局
{
"query": {
"term": {
"title": "crime"
}
},
"highlight": {
"pre_tags": ["<b>"],
"post_tags": ["</b>"],
"fields": {
"title": {}
}
}
}
局部
{
"query": {
"term": {
"title": "crime"
}
},
"highlight": {
"fields": {
"title": {
"pre_tags": ["<b>"],
"post_tags": ["</b>"]
}
}
}
}
需要匹配
有时,尤其是在使用多个高亮字段时,只需要显示跟查询匹配的字段。为了触发此行为,要
把require_field_match属性设为true。把该属性设为false将导致所有词条都高亮显示,即
使是在跟查询不匹配的字段中
{
"query": {
"term": {
"name": "test"
}
},
"highlight": {
"require_field_match": "true",
"fields": {
"name": {
"pre_tags": ["<b>"],
"post_tags": ["<b>"]
},
"description": {
"pre_tags": ["<b>"],
"post_tags": [
"</b>"
]
}
}
}
}
信息高亮器(暂时不care)
7 验证查询
有时,应用程序发送到Elasticsearch的查询是自动从多个条件生成的,甚至更糟,它们是通
过某种向导生成,最终用户可以在其中创建复杂的查询。问题是,查询的正确与否,有时并不容
易分辨。为了解决这个问题, Elasticsearch公开了验证API。
{
"query": {
"bool": {
"must": {
"term": {
"title": "crime"
}
},
"should": {
"range : {
"year": {
"from": 1900,
"to": 2000
}
}
},
"must_not": {
"term": {
"otitle": "nothing"
}
}
}
}
验证API还可以检测其他错误,例如,格式不正确的数字或其他映射相关的问题。可惜,由
于我们的应用程因为缺乏错误信息中的结构,不是很容易发现问题
8 数据排序
默认排序
在底层, Elasticsearch把它当作如下查询:
{
"query" : {
"terms" : {
"title" : [ "crime", "front", "punishment" ],
"minimum_match" : 1
}
},
"sort" : { "_score" : "desc" }
}
选择用于排序的字段
"sort" : [
{ "title" : "asc" }
]
一般来说,对一个未经分析的字段排序是一个好主意,我们可以对具有多个值的字段排序,
但在大多数情况下,没有多大意义,因此使用有限。例如,我们使用两个不同的字段,一个作为
排序,另一个作为搜索,修改title字段。更改过的title字段定义可能类似于下面的代码
"title" : {
"type": "string",
"fields": {
"sort": { "type" : "string", "index": "not_analyzed" }
}
}
或者
{
"query" : {
"match_all" : { }
},
"sort" : [
{"title.sort" : "asc" }
]
}
指定缺少字段的行为
当有些与查询匹配的文档没有我们要排序的字段时,会怎么样?默认情况下,没有给定字段
的文档,如果是升序排,则会出现在第一个;如果是降序排,则出现在最后一个。然而,有时这
不是我们想要的。
使用数字字段排序时,可以更改Elasticsearch对缺少字段的文档的默认行为。例如以下查询:
{
"query" : {
"match_all" : { }
},
"sort" : [
{ "section" : { "order" : "asc", "missing" : "_last" } }
]
}
注意,查询中sort节点的扩展部分添加了missing参数。通过把missing参数设为_last,
Elasticsearch将把缺乏给定字段的文档放在结果列表的底部。设置为_first,则会把缺乏给定字
段的文档放在结果列表的顶部。值得一提的是,除了_last和_first值, Elasticsearch允许我们
使用任意数字。在这种情况下,一个没有给定字段的文档将被视为该文档具有给定的值
动态条件+排序规则和国家特有字符(暂不care)
9 查询重写(暂不care)