空查询
空查询将返回所有索引库(indices)中的所有文档:
GET /_search
{}
只用一个查询字符串,你就可以在一个、多个或者 _all 索引库(indices)和一个、多个或者所有types中查询:
GET /index_2014*/type1,type2/_search
{}
同时你可以使用 from 和 size 参数来分页:
GET /_search
{
"from": 30,
"size": 10
}
查询表达式
要使用这种查询表达式,只需将查询语句传递给 query 参数:
GET /_search
{
"query": YOUR_QUERY_HERE
}
空查询(empty search) —{}— 在功能上等价于使用 match_all 查询, 正如其名字一样,匹配所有文档:
GET /_search
{
"query": {
"match_all": {}
}
}
一个查询语句 的典型结构:
{
QUERY_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
如果是针对某个字段,那么它的结构如下:
{
QUERY_NAME: {
FIELD_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}
举个例子,你可以使用 match 查询语句 来查询 tweet 字段中包含 elasticsearch 的 tweet:
{
"match": {
"tweet": "elasticsearch"
}
}
完整的查询请求如下:
GET /_search
{
"query": {
"match": {
"tweet": "elasticsearch"
}
}
}
查询
单词查询(Single word query)
{
"query": {
"match": {
"title": "QUICK!"
}
}
}
多词查询(Multi-word Queries)
{
"query": {
"match": {
"title": "BROWN DOG!"
}
}
}
#内部它需要执行两个term查询,然后将它们的结果合并来得到整体的结果,它会将两个term查询通过一个bool查询组织在一起
提高精度(Improving Precision)
{
"query": {
"match": {
"title": {
"query": "BROWN DOG!",
"operator": "and"
}
}
}
}
控制精度(Controlling Precision)
在all和any中选择有种非黑即白的感觉。如果用户指定了5个查询词条,而一份文档只包含了其中的4个呢?将"operator"设置成"and"会将它排除在外。
{
"query": {
"match": {
"title": {
"query":"quick brown dog",
"minimum_should_match": "75%"
}
}
}
}
合并查询(Combining Queries)
通过must,must_not以及should参数来接受多个查询
title字段中含有词条quick,且不含有词条lazy的任何文档都会被作为结果返回。目前为止,它的工作方式和bool过滤器十分相似。
差别来自于两个should语句,它表达了这种意思:一份文档不被要求需要含有词条brown或者dog,但是如果它含有了,那么它的相关度应该更高。
{
"query": {
"bool": {
"must": { "match": { "title": "quick" }},
"must_not": { "match": { "title": "lazy" }},
"should": [
{ "match": { "title": "brown" }},
{ "match": { "title": "dog" }}
]
}
}
}
控制精度(Controlling Precision)
所有的must语句都需要匹配,而所有的must_not语句都不能匹配,但是should语句需要匹配多少个呢?默认情况下,should语句一个都不要求匹配,只有一个特例:如果查询中没有must语句,那么至少要匹配一个should语句。
{
"query": {
"bool": {
"should": [
{ "match": { "title": "brown" }},
{ "match": { "title": "fox" }},
{ "match": { "title": "dog" }}
],
"minimum_should_match": 2
}
}
}
minimum_should_match参数来控制should语句需要匹配的数量,该参数可以是一个绝对数值或者一个百分比
下面两个子句分别等价
{
"match": { "title": "brown fox"}
}
{
"bool": {
"should": [
{ "term": { "title": "brown" }},
{ "term": { "title": "fox" }}
]
}
}
{
"match": {
"title": {
"query": "brown fox",
"operator": "and"
}
}
}
{
"bool": {
"must": [
{ "term": { "title": "brown" }},
{ "term": { "title": "fox" }}
]
}
}
{
"match": {
"title": {
"query": "quick brown fox",
"minimum_should_match": "75%"
}
}
}
{
"bool": {
"should": [
{ "term": { "title": "brown" }},
{ "term": { "title": "fox" }},
{ "term": { "title": "quick" }}
],
"minimum_should_match": 2
}
}
提升查询子句(Boosting Query Clause)
{
"query": {
"bool": {
"must": {
"match": {
"content": {
"query": "full text search",
"operator": "and"
}
}
},
"should": [
{ "match": { "content": "Elasticsearch" }},
{ "match": { "content": "Lucene" }}
]
}
}
}
指定一个boost值来控制每个查询子句的相对权重
{
"query": {
"bool": {
"must": {
"match": {
"content": {
"query": "full text search",
"operator": "and"
}
}
},
"should": [
{ "match": {
"content": {
"query": "Elasticsearch",
"boost": 3
}
}},
{ "match": {
"content": {
"query": "Lucene",
"boost": 2
}
}}
]
}
}
}
控制分析(Controlling Analysis) //暂不理解
{
"query": {
"bool": {
"should": [
{ "match": { "title": "War and Peace" }},
{ "match": { "author": "Leo Tolstoy" }}
]
}
}
}
{
"query": {
"bool": {
"should": [
{ "match": { "title": "War and Peace" }},
{ "match": { "author": "Leo Tolstoy" }},
{ "bool": {
"should": [
{ "match": { "translator": "Constance Garnett" }},
{ "match": { "translator": "Louise Maude" }}
]
}}
]
}
}
}
bool查询中包含的译者查询子句只占了总分值的三分之一,如果我们将译者查询子句放到和标题及作者相同的层次上,就会减少标题和作者子句的权重,让它们各自只占四分之一。
{
"query": {
"bool": {
"should": [
{ "match": {
"title": {
"query": "War and Peace",
"boost": 2
}}},
{ "match": {
"author": {
"query": "Leo Tolstoy",
"boost": 2
}}},
{ "bool": {
"should": [
{ "match": { "translator": "Constance Garnett" }},
{ "match": { "translator": "Louise Maude" }}
]
}}
]
}
}
}
boost值的范围推荐在1和10之间
查询策略
最佳字段(Best fields)
bool should查询是如何计算得到其分值的
{
"query": {
"bool": {
"should": [
{ "match": { "title": "Brown fox" }},
{ "match": { "body": "Brown fox" }}
]
}
}
}
运行should子句中的两个查询
相加查询返回的分值
将相加得到的分值乘以匹配的查询子句的数量
除以总的查询子句的数量
dis_max查询
返回匹配了任何查询的文档,并且分值是产生了最佳匹配的查询所对应的分值
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Brown fox" }},
{ "match": { "body": "Brown fox" }}
]
}
}
}
tie_breaker
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
],
"tie_breaker": 0.3
}
}
}
tie_breaker参数会让dis_max查询的行为更像是dis_max和bool的一种折中。
dis_max最佳字段(Best fields)、bool多数字段(Most fields)的折中
它会通过下面的方式改变分值计算过程:
取得最佳匹配查询子句的_score。
将其它每个匹配的子句的分值乘以tie_breaker。
将以上得到的分值进行累加并规范化。
通过tie_breaker参数,所有匹配的子句都会起作用,只不过最佳匹配子句的作用更大。
multi_match、match、dis_max、bool 的转换
multi_match查询 下两个查询等价
{
"dis_max": {
"queries": [
{
"match": {
"title": {
"query": "Quick brown fox",
"minimum_should_match": "30%"
}
}
},
{
"match": {
"body": {
"query": "Quick brown fox",
"minimum_should_match": "30%"
}
}
},
],
"tie_breaker": 0.3
}
}
{
"multi_match": {
"query": "Quick brown fox",
"type": "best_fields",
"fields": [ "title", "body" ],
"tie_breaker": 0.3,
"minimum_should_match": "30%"
}
}
注意到以上的type属性为best_fields。
minimum_should_match和operator参数会被传入到生成的match查询中
在字段名中使用通配符
{
"multi_match": {
"query": "Quick brown fox",
"fields": "*_title"
}
}
提升个别字段
{
"multi_match": {
"query": "Quick brown fox",
"fields": [ "*_title", "chapter_title^2" ]
}
}
多字段映射(Multifield Mapping) 与 多数字段(Most fields)
跨字段(Cross fields)
临近匹配
短语匹配(Phrase Matching)
就像一提到全文搜索会首先想到match查询一样,当你需要寻找邻近的几个单词时,你会使用match_phrase查询:
GET /my_index/my_type/_search
{
"query": {
"match_phrase": {
"title": "quick brown fox"
}
}
}
位置信息可以被保存在倒排索引(Inverted Index)中,像match_phrase这样位置感知(Position-aware)的查询能够使用位置信息来匹配那些含有正确单词出现顺序的文档,在这些单词间没有插入别的单词。
短语是什么
对于匹配了短语"quick brown fox"的文档,下面的条件必须为true:
- quick,brown和fox必须全部出现在某个字段中。
- brown的位置必须比quick的位置大1。
- fox的位置必须比quick的位置大2。
如果以上的任何条件没有被满足,那么文档就不能被匹配。
混合起来(Mixing it up)
精确短语(Exact-phrase)匹配也许太过于严格了。也许我们希望含有"quick brown fox"的文档也能够匹配"quick fox"查询,即使位置并不是完全相等的。
我们可以在短语匹配使用slop参数来引入一些灵活性:
GET /my_index/my_type/_search
{
"query": {
"match_phrase": {
"title": {
"query": "quick fox",
"slop": 1
}
}
}
}
slop参数告诉match_phrase查询词条能够相隔多远时仍然将文档视为匹配。相隔多远的意思是,你需要移动一个词条多少次来让查询和文档匹配?
待续
部分匹配(Partial Matching)前缀查询
前缀查询(Prefix Query)
我们可以通过一个简单的prefix查询来得到所有以W1开头的邮政编码:
GET /my_index/address/_search
{
"query": {
"prefix": {
"postcode": "w1"
}
}
}
通配符
wildcard查询和prefix查询类似,也是一个基于词条的低级别查询。但是它能够让你指定一个模式(Pattern),而不是一个前缀(Prefix)。它使用标准的shell通配符:?用来匹配任意字符,*用来匹配零个或者多个字符。
以下查询能够匹配包含W1F 7HW和W2F 8HW的文档:
GET /my_index/address/_search
{
"query": {
"wildcard": {
"postcode": "W?F*HW"
}
}
}
正则表达式
假设现在你想匹配在W地域(Area)的所有邮政编码。使用前缀匹配时,以WC开头的邮政编码也会被匹配,在使用通配符查询时也会遇到类似的问题。我们只想匹配以W开头,紧跟着数字的邮政编码。使用regexp查询能够让你写下更复杂的模式:
GET /my_index/address/_search
{
"query": {
"regexp": {
"postcode": "W[0-9].+"
}
}
}
这个正则表达式的规定了词条需要以W开头,紧跟着一个0到9的数字,然后是一个或者多个其它字符。
注意
prefix,wildcard以及regexp查询基于词条进行操作。如果你在一个analyzed字段上使用了它们,它们会检查字段中的每个词条,而不是整个字段。
待续
参考: