原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/getting-started-search.html
elasticsearch版本:6.5
1、示例数据
既然我们已经大致了解了基础知识,那么让我们试着研究一个更现实的数据集。我准备了一个客户银行账户信息的虚构JSON文档样本。每个文档都有以下架构:
{
"account_number": 0,
"balance": 16623,
"firstname": "Bradshaw",
"lastname": "Mckenzie",
"age": 29,
"gender": "F",
"address": "244 Columbus Place",
"employer": "Euron",
"email": "[email protected]",
"city": "Hobucken",
"state": "CO"
}
出于好奇,此数据是使用www.json-generator.com/生成的,因此请忽略数据的实际值和语义,因为它们都是随机生成的
2、示例数据下载
您可以从这里下载示例数据集(accounts.json)。将其提取到当前目录,然后按如下方式将其加载到集群中:
curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_doc/_bulk?pretty&refresh" --data-binary "@accounts.json"
curl "localhost:9200/_cat/indices?v"
得到的响应如下:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open bank l7sSYV2cQX 4 5 1 1000 0 128.6kb 128.6kb
这意味着我们刚刚成功地将1000个文档批量索引到银行索引中(在_doc类型下)。
3、Search API
现在让我们从一些简单的搜索开始。运行搜索有两种基本方法:一种是通过REST请求URI发送搜索参数,另一种是通过REST请求主体发送搜索参数。请求主体方法允许您更具表现力,还可以用更可读的JSON格式定义搜索。我们将尝试一个请求URI方法的示例,但在本教程的其余部分中,我们将专门使用请求体方法。
用于搜索的REST API可以从_search访问。此示例返回银行索引中的所有文档:
GET /bank/_search?q=*&sort=account_number:asc&pretty
我们先分析一下搜索电话。我们正在银行索引中搜索(_search,q=*参数指示ElasticSearch匹配索引中的所有文档。sort=account_number:asc参数指示使用每个文档的account_number字段按升序对结果进行排序。同样,pretty参数只告诉elasticsearch返回漂亮打印的JSON结果。
得到的响应为(部分显示):
{
"took" : 63,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1000,
"max_score" : null,
"hits" : [ {
"_index" : "bank",
"_type" : "_doc",
"_id" : "0",
"sort": [0],
"_score" : null,
"_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"[email protected]","city":"Hobucken","state":"CO"}
}, {
"_index" : "bank",
"_type" : "_doc",
"_id" : "1",
"sort": [1],
"_score" : null,
"_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"[email protected]","city":"Brogan","state":"IL"}
}, ...
]
}
}
通过这个响应,我们可以得到一下内容:
took — elasticsearch执行查询消耗的时间,单位是毫秒
timed_out — 告诉我们查询是否超时了
_shards — 告诉我们有多少个分配被查询,其中有多少个成功的,多少个失败的
hits — 查询命中的结果
hits.total — 总共有多少个文档满足我们的查询条件
hits.hits — 查询到的数据
hits.sort — 查询结果的排序字段,如果没有指定按照score排序
hits._score 和 max_score — 查询的得分,最高得分
下面是上面使用request 请求体方法进行的相同搜索:
GET /bank/_search
{
"query":{"match_all":{}},
"sort":[
{"account_number":"asc"}
]
}
这里的不同点就是用一个JSON风格的request请求体代替了q=*。
4、Query语句简单介绍
ElasticSearch提供了一种JSON风格的语言,您可以使用它来执行查询。这被称为Query DSL。查询语言非常全面,乍一看可能很吓人,但实际学习它的最好方法是从几个基本示例开始。
回到上一个例子,我们执行这个查询:
GET /bank/_search
{
"query":{"match_all":{}}
}
仔细分析上面的内容,query部分告诉我们查询定义是什么,match_all部分是我们想要运行的查询类型。match_all查询只是搜索指定索引中的所有文档。
除了查询参数,我们还可以传递其他参数来影响搜索结果。在上面部分的示例中,我们传入了sort,这里我们传入了size:
GET /bank/_search
{
"query":{"match_all":{}},
"size":1
}
这里需要注意,如果size参数没有指定,默认值是10.
接下来的例子是查询一个文档,返回从10到19这10个结果:
GET /bank/_search
{
"query":{"match":{}},
"from": 10,
"size": 10
}
from参数指定的是从第几条记录开发返回,默认值是0,size参数指定的是返回结果的条数。这个功能在分页产找时很重要。
下面这个示例执行“全部匹配”,并按帐户余额降序排序结果,并返回前10个(默认大小)文档:
GET /bank/_search
{
"query":{"match_all":{}},
"sort":{"balance":{"order":"desc"}}
}
5、search查询
我们已经看到了一些基本的搜索参数,那么让我们深入研究一下Query DSL。让我们先看看返回的文档字段。默认情况下,作为所有搜索的一部分返回完整的JSON文档。这被称为“source”(搜索命中中的“_source”字段)。如果我们不希望返回整个_source文档,我们可以只请求返回_source中的几个字段。
此示例显示如何从搜索中返回两个字段,即account_number和balance(在_source内):
GET /bank/_search
{
"query":{"match_all":{}},
"_source":["account_number","balance"]
}
这个查询的响应中将只有一个_source字段,并且里面只有account_number和balance两个字段。如果你会SQL语句,那么这个请求就类似于SQL中的select from 字段列表。
现在让我们继续关注query部分,上面已经看到match_all查询是查询所有的文档。现在,让我们介绍一个名为match query的新查询,它可以被视为基本的字段化搜索查询(即针对特定字段或一组字段进行的搜索)。
下面这个列子返回account_number是20的结果:
GET /bank/_search
{
"query":{"match":{"account_number":20}}
}
下面的例子返回的是address字段中包含mill的结果:
GET /bank/_search
{
"quer":{"match":{"address":"mill"}}
}
下面的例子返回的是address字段中包含mill或lane的结果:
GET /bank/_search
{
"query":{"match":{"address":"mill lane"}}
}
下面的例子返回的是address字段中包含mill lane的结果:
GET /bank/_search
{
"query":{"match_phrase":{"address":"mill lane"}}
}
接下来我们看下bool query,bool查询允许我们组合使用布尔逻辑。
下面的例子组合了两个match查询,将返回address字段中包含mill和lane的记录:
GET /bank/_search
{
"query":{
"bool":{
"must":[
{"match":{"address":"mill"}},
{"match":{"address":"lane"}}
]
}
}
}
这个例子中要求must大括号里面的查询条件必须都为真,才认为满足查询条件。
相反,下面这个例子用手should组装两个match条件,返回的结果将是address字段里面包含mill或是包含lane的记录:
GET /bank/_search
{
"query":{
"bool":{
"should":{
{"match":{"address":"mill"}},
{"match":{"address":"lane"}}
}
}
}
}
线面的例子返回的是address字段里面既不包含mill也不包含lane的记录:
GET /bank/_search
{
"query":{
"bool":{
"must_not":[
{"match":{"address","mill"}},
{"match":{"address","lane"}}
]
}
}
}
我们可以在bool查询中自由的组装must,should和must_not,在bool中组装bool查询,来实现更加复杂的逻辑。
下面的例子是年龄为40岁并且state不是ID的记录:
GET /bank/_search
{
"query":{
"bool":{
"must":[
{"match":{"age":40}}
],
"must_not":[
{"match":{"state":"ID"}}
]
}
}
}
未完待续...