安装完ElasticSearch 和 Kibana后我们开始学习
为了方便测试,使用kibana的dev tool来进行学习测试:
向 Elasticsearch 索引 customer 的 _doc 类型的文档 id 为 1 的文档发送 PUT 请求的例子。
请求体为 JSON 格式,包含一个字段 name 和其值 DLBoy。 Elasticsearch 支持多种请求方法来对索引进行操作,其中包括 GET、POST、PUT、DELETE 等等。
在这个例子中,我们使用的 PUT 方法将更新或创建一个新的文档:
PUT /customer/_doc/1
{
"name": "DLBoy"
}
/customer/_doc/1
,其中`customer`是索引的名称,`_doc`通常是文档类型(在Elasticsearch 7.x及更高版本中,文档类型通常被忽略),而`1`是文档的唯一标识ID。
使用 PUT 方法提交文档时,如果指定的 id 已经存在,则该文档将被更新;如果不存在则该文档将被创建。在 POST 方法中,不需要提供 id 参数, Elasticsearch 会生成一个唯一的 id 。
数据的格式如下:
/opt/
下面执行
curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_bulk?pretty&refresh" --data-binary "@/opt/accounts.json"
curl
: 这是一个命令行工具,用于发起HTTP请求。-H "Content-Type: application/json"
: 这是HTTP请求头,指定请求的内容类型为JSON。-XPOST
: 这指示curl执行HTTP POST请求。"localhost:9200/bank/_bulk?pretty&refresh"
: 这是目标Elasticsearch服务器的URL,它指定了索引名称"bank",并在URL中使用"_bulk"来指示批量导入操作。pretty
参数是可选的,用于格式化响应以使其更易阅读,refresh
参数用于在导入完成后刷新索引,以使新数据立即可用。--data-binary "@/opt/accounts.json"
: 这是HTTP请求的数据部分,它指定了要导入的数据文件的路径,这里是"/opt/accounts.json"。@
符号表示要上传文件的路径。这个文件包含了要批量导入的JSON数据。查看状态
curl "localhost:9200/_cat/indices?v=true" | grep bank
match_all
表示查询所有的数据,sort
即按照什么字段排序
GET /bank/_search
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" }
]
}
这是一个Elasticsearch批量导入数据的响应示例。响应包含了以下信息:
"took" : 1
: 表示处理请求所花费的时间,以毫秒为单位。"timed_out" : false
: 表示请求没有超时。"_shards"
: 提供了与索引分片相关的信息,包括总分片数、成功的分片数、跳过的分片数和失败的分片数。"total"
: 表示索引总共包含了1个分片。在分布式环境下,索引通常被分成多个分片以提高性能和可伸缩性。这里的值为1,表示索引可能是单一分片的。"successful"
: 表示成功完成的分片数。在这里,所有的分片操作都成功,所以值为1。"skipped"
: 表示跳过的分片数。在这个响应中,没有分片被跳过,所以值为0。"failed"
: 表示失败的分片数。在这个响应中,没有分片失败,所以值为0。"hits"
: 这是一个包含有关查询匹配文档的信息的部分。"total"
: 提供了匹配查询条件的总文档数,这里是1000个文档。这是符合查询条件的文档总数。"relation"
: 表示与总文档数的关系,这里是"eq",表示匹配文档的数量等于总文档数。其他可能的关系包括"gte"(大于或等于)、"lte"(小于或等于)等,根据查询条件的具体情况而定。"hits"
: 这是一个文档数组,包含了查询匹配的文档。每个文档都包括了以下信息:这个响应示例表明批量导入操作成功,共导入了1000个文档,并提供了匹配的文档详细信息。这些信息可用于后续的搜索和分析操作。
from和size两个字段
GET /bank/_search
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" }
],
"from": 10,
"size": 10
}
如果要在字段中搜索特定字词,可以使用match
查询address 字段中包含 mill 或者 lane的数据;
GET /bank/_search
{
"query": {
"match": {
"address": "Holmes Lane"
}
}
}
"query"
: 查询请求的主体,指示Elasticsearch执行查询操作。"match"
: 查询类型,表示执行一个文本匹配查询。"address"
: 要匹配的字段名称,这里是"address"字段。"Holmes Lane"
: 要匹配的文本内容,这里是"Holmes Lane"。查询将在"address"字段中查找包含"Holmes Lane"的文本。由于ES底层是按照分词索引的,所以上述查询结果是address 字段中包含 Holmes 或者 Lane 的数据
查询的条件是 address字段中包含 "Holmes Lane",则可以使用match_phrase
GET /bank/_search
{
"query": {
"match_phrase": {
"address": "Holmes Lane"
}
}
}
"query"
: 查询请求的主体,指示Elasticsearch执行查询操作。"match_phrase"
: 查询类型,表示执行一个短语匹配查询。"address"
: 要匹配的字段名称,这里是"address"字段。"Holmes Lane"
: 要匹配的短语,这里是"Holmes Lane"。查询将在"address"字段中查找包含完整短语"Holmes Lane"的文本。如果要构造更复杂的查询,可以使用bool
查询来组合多个查询条件。
GET /bank/_search
{
"query": {
"bool": {
"must": [
{ "match": { "age": "40" } }
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}
"query"
: 查询请求的主体,指示Elasticsearch执行查询操作。"bool"
: 查询类型,表示执行一个布尔查询,它可以包含多个条件。"must"
: 这是一个数组,包含了必须匹配的条件。在这里,我们要求文档的"age"字段必须匹配值"40"。"must_not"
: 这也是一个数组,包含了不能匹配的条件。在这里,我们要求文档的"state"字段不能匹配值"ID"。must,should,must_not
和 filter
都是bool
查询的子句。
那么filter
和query
子句有啥区别呢?
在bool
查询的子句中同时具备query,must 和 filter
GET /bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"state": "ND"
}
}
],
"filter": [
{
"term": {
"age": "40"
}
},
{
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
]
}
}
}
Elasticsearch查询的示例,使用HTTP GET请求来搜索名为"bank"的索引中的文档。这个查询是一个复杂的布尔查询,包含了多个子查询条件,同时指定了必须匹配的条件和过滤条件。以下是这个查询的各个部分的解释:
GET
,表示发起一个查询请求。/bank/_search
,这是指定要搜索的索引名称为"bank",并且执行搜索操作。"query"
: 查询请求的主体,指示Elasticsearch执行查询操作。"bool"
: 查询类型,表示执行一个布尔查询,它可以包含多个条件。"must"
: 这是一个数组,包含了必须匹配的条件。在这里,我们要求文档的"state"字段必须匹配值"ND",即北达科他州。"filter"
: 这是一个数组,包含了过滤条件,这些条件用于排除文档。在这里,有两个过滤条件:"term"
: 这是一个精确匹配查询条件,要求文档的"age"字段必须精确匹配值"40"。"range"
: 这是一个范围查询条件,要求文档的"balance"字段的值必须在20000到30000之间(包括20000和30000)。所以,这个查询的目的是从"bank"索引中查找文档,这些文档同时满足以下条件:位于北达科他州("state"字段匹配"ND"),年龄为40,账户余额在20000到30000之间。
只包含filter的查询:
GET /bank/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"age": "40"
}
},
{
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
]
}
}
}
在Elasticsearch中,query
和filter
都用于定义搜索条件,但它们之间有重要的区别,主要涉及到搜索的目的和结果处理方式。以下是它们的主要区别:
总之,query
主要用于搜索和排序文档,通常在需要考虑相关性的情况下使用,如全文搜索。而filter
主要用于筛选文档,通常在需要精确匹配和排除的情况下使用,如范围查询、精确匹配、布尔条件等。根据搜索需求,可以选择使用query
、filter
或它们的组合,以达到所需的搜索目标。
我们知道SQL中有group by,在ES中它叫Aggregation,即聚合运算。
比如我们希望计算出account.json的数据中每个州的统计数量, 使用aggs
关键字对state
字段聚合,被聚合的字段无需对分词统计,所以使用state.keyword
对整个字段统计
GET /bank/_search
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword"
}
}
}
}
所以,这个查询的目的是执行一个名为"group_by_state"的聚合,根据文档中的"state.keyword"字段的值进行分组。它将生成一个分组列表,其中包含每个不同州的值,并统计每个州的文档数量。由于"size"设置为0,不会返回实际文档结果,只返回聚合结果,以供进一步分析或显示聚合数据。这种聚合操作对于分析文档集的统计信息非常有用。
Elasticsearch聚合操作的响应结果,具体包括了"aggregations"部分解释:
在这个示例中,"group_by_state"聚合对"state.keyword"字段进行了分组,并列出了每个州的文档数量。例如,"TX"(得克萨斯州)有30个文档,"MD"(马里兰州)有28个文档,以此类推。这种聚合操作有助于了解文档集中各个分组的统计信息,通常用于数据分析和可视化。
ES处理聚合条件的嵌套。
计算每个州的平均结余。涉及到的就是在对state分组的基础上,嵌套计算avg(balance):
GET /bank/_search
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword"
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
所以,这个查询的目的是执行一个名为"group_by_state"的聚合,根据文档中的"state.keyword"字段的值进行分组。在每个分组内,还执行了一个名为"average_balance"的嵌套聚合,计算每个州的平均账户余额。由于"size"设置为0,不会返回实际文档结果,只返回聚合结果,以供进一步分析或显示聚合数据。这种聚合操作对于分析文档集的统计信息非常有用,包括平均值、总和、最小值、最大值等。
这是执行Elasticsearch聚合操作后的响应结果,具体包括了"aggregations"部分的解释:
在这个示例中,"group_by_state"聚合对"state.keyword"字段进行了分组,列出了每个州的文档数量,并计算了每个州的平均账户余额。例如,"TX"(得克萨斯州)有30个文档,平均账户余额为26073.3,"MD"(马里兰州)有28个文档,平均账户余额为26161.535714285714,以此类推。这种聚合操作非常有助于对文档集进行统计和分析,以获得有关每个分组的信息。
通过在aggs中对嵌套聚合的结果进行排序
对嵌套计算出的avg(balance),这里是average_balance,进行排序
GET /bank/_search
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword",
"order": {
"average_balance": "desc"
}
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
这个查询的目的是执行一个名为"group_by_state"的聚合,根据文档中的"state.keyword"字段的值进行分组,同时计算每个州的平均账户余额,并按照平均余额的降序排列结果。由于"size"
设置为0,不会返回实际文档结果,只返回聚合结果,以供进一步分析或显示聚合数据。这种聚合操作有助于找到平均账户余额最高的州。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。