ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

es创建文档,插入、查询、聚合查询

2022-05-04 13:34:59  阅读:182  来源: 互联网

标签:count doc 查询 state 文档 match key es


插入数据
一旦你启动并运行集群,你就可以创建数据了。Elasticsearch 有多种方式插入数据,但最终它们都执行同样的操作,将 JSON 文档放入 Elasticsearch 索引中。

你可以使用简单的 PUT 请求去执行操作,请求须指定文档的索引名称,唯一的文档 ID,以及请求体中一个或多个键值对。

PUT /customer/_doc/1
{
  "name": "John Doe"
}

这个请求(如不存在)将自动创建一个 ID 为 1 的新文档,并储存键值对,并为其建立索引。

由于这是一个新文档,返回的结果显示新创建的文档版本号为 1:

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 26,
  "_primary_term" : 4
}

你可以在集群里任意节点去获取文档,你也可以 GET 请求指定 ID 文档

GET /customer/_doc/1

返回结果显示找到里对应的指定文档,并返回了原始字段信息

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 26,
  "_primary_term" : 4,
  "found" : true,
  "_source" : {
    "name": "John Doe"
  }
}

批量插入数据
如果有大量的文档需要插入,你可以使用 BULK API 批量插入数据。使用 Bulk API 要比单独请求提交要快,是因为它最大限度地减少了网络传输次数。

最佳批量插入大小取决于许多因素:文档大小和复杂性、索引、搜索负载以及集群的可用资源。每次批量处理最好在 1000 ~ 5000 个文档,文档大小最好是在 5M ~ 15M 之间。

将数据批量导入 Elasticsearch,你就可以开始搜索和分析了。
下载 acounts.jsondemo数据。随机生成的 demo 数据展示了以下的用户信息:

{
    "account_number": 0,
    "balance": 16623,
    "firstname": "Bradshaw",
    "lastname": "Mckenzie",
    "age": 29,
    "gender": "F",
    "address": "244 Columbus Place",
    "employer": "Euron",
    "email": "bradshawmckenzie@euron.com",
    "city": "Hobucken",
    "state": "CO"
}

使用_bulk 请求将账户数据导入到银行文档中:

curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_bulk?pretty&refresh" --data-binary "@C:/user/accounts.json


注意:
@C:/user/accounts.json,是该文件再你电脑中的存储位置


返回结果显示了成功导入了 1000 个文档


" curl "localhost:9200/_cat/indices?v"

health status index uuid pri rep docs.count docs.deleted store.size pri.store.size yellow open bank l7sSYV2cQXmu6_4rJWVIww 5 1 1000 0 128.6kb 128.6kb

搜索

一旦你开始在 Elasticsearch 插入数据,你就可以通过_search 方式发送请求来进行搜索,如果使用匹配搜索功能,在请求体中使用 Elasticsearch Query DSL 指定搜索条件。你也可以在请求头指定要搜索的索引名称。

如下图所示:搜索银行索引中,所有账号按照 account_number 排序:

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}

默认情况下,会返回符合条件搜索的前 10 个文档:

{
  "took" : 63,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
        "value": 1000,
        "relation": "eq"
    },
    "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":"bradshawmckenzie@euron.com","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":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
    }, ...
    ]
  }
}

响应体里还提供了有关搜索请求的相关信息:

took – 查询花费时长(毫秒)
timed_out – 请求是否超时
_shards – 搜索了多少分片,成功、失败或者跳过了多个分片(明细)
max_score – 最相关的文档分数
hits.total.value - 找到的文档总数
hits.sort - 文档排序方式 (如没有则按相关性分数排序)
hits._score - 文档的相关性算分 (match_all 没有算分)

 每个搜索请求都是独立的:Elasticsearch 不维护任何请求中的状态信息。如果做分页的话,请在请求中指定 From 和 Size 参数。
如图所示:搜索第 10 到 19 的数据

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ],
  "from": 10,
  "size": 10
}

现在你已经了解如何提交最基本的搜索请求了,则可以开始构建比 match_all 更有趣的查询了。

想搜索特定的字段,可以使用匹配查询。如下所示,请求搜索地址字段以查询地址中包含 mill 或 lane 的客户

GET /bank/_search
{
  "query": { "match": { "address": "mill lane" } }
}

如果要全部匹配而不是仅仅是包含关键字之一,你需要使用 match_phrase 而不是 match。(译者注:match 和 match_phrase 的区别就像是 or 和 and 的区别) 如图所示:

在请求中查询地址中同时包含 mill 和 lane 的客户:

 

GET /bank/_search
{
  "query": { "match_phrase": { "address": "mill lane" } }
}

如果要构造更复杂的查询,可以使用布尔查询来组合多个查询条件,must match、should match、must not match

如图所示:请求在银行索引里搜索年龄是 40 的,但不居住在爱达荷州 (ID) 的客户:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}

布尔查询中每个 must,should,must_not 都被称为查询子句。每个
must 或者 should 查询子句中的条件都会影响文档的相关得分。得分越高,文档跟搜索条件匹配得越好。默认情况下,Elasticsearch 返回的文档会根据相关性算分倒序排列。

must_not 子句中认为是过滤条件。它会过滤返回结果,但不会影响文档的相关性算分,你还可以明确指定任意过滤条件去筛选结构化数据文档。

如图所示:请求搜索余额在 20000 ~ 30000(包括 30000) 之间的账户

GET /bank/_search
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

 使用聚合分析

Elasticsearch 聚合让你看到一些有关搜索结果元信息,返回结果能显示例如:“德克萨斯州有多少个开户的人?” 或者 “田纳西州的平均帐户余额是多少?”。你可以搜索文档,过滤 hits,使用聚合去分析并返回结果。

如图所示:请求使用 terms 聚合对 bank 索引中对所有还在账户进行分组,并安装返回前 10 个账户数最多的州:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}
{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped" : 0,
    "failed": 0
  },
  "hits" : {
     "total" : {
        "value": 1000,
        "relation": "eq"
     },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets" : [ {
        "key" : "ID",
        "doc_count" : 27
      }, {
        "key" : "TX",
        "doc_count" : 27
      }, {
        "key" : "AL",
        "doc_count" : 25
      }, {
        "key" : "MD",
        "doc_count" : 25
      }, {
        "key" : "TN",
        "doc_count" : 23
      }, {
        "key" : "MA",
        "doc_count" : 21
      }, {
        "key" : "NC",
        "doc_count" : 21
      }, {
        "key" : "ND",
        "doc_count" : 21
      }, {
        "key" : "ME",
        "doc_count" : 20
      }, {
        "key" : "MO",
        "doc_count" : 20
      } ]
    }
  }
}{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped" : 0,
    "failed": 0
  },
  "hits" : {
     "total" : {
        "value": 1000,
        "relation": "eq"
     },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets" : [ {
        "key" : "ID",
        "doc_count" : 27
      }, {
        "key" : "TX",
        "doc_count" : 27
      }, {
        "key" : "AL",
        "doc_count" : 25
      }, {
        "key" : "MD",
        "doc_count" : 25
      }, {
        "key" : "TN",
        "doc_count" : 23
      }, {
        "key" : "MA",
        "doc_count" : 21
      }, {
        "key" : "NC",
        "doc_count" : 21
      }, {
        "key" : "ND",
        "doc_count" : 21
      }, {
        "key" : "ME",
        "doc_count" : 20
      }, {
        "key" : "MO",
        "doc_count" : 20
      } ]
    }
  }
}

如图所示:在返回结果中 buckets 的值是字段 state 的桶。 doc_count 表示每州的账户数。你可以看到爱达荷州中有 27 个帐户,由于 "size": 0 表示了返回只有聚合结果,无具体数据。

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

你可以使用组合聚合来构建更为复杂的统计数据。如图所示:请求将 avg 聚合嵌套在 group_by_state 聚合内,以计算每州的平均账户余额

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "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"
          }
        }
      }
    }
  }
}

除了这些基本的桶跟指标聚合之外,Elasticsearch 还提供了其他类型的聚合,用于对多个字段进行操作和分析特定类型的数据,如日期、IP 和地理数据。你还可以将单个聚合的结果送到管道聚合中进行深一步分析。

 

标签:count,doc,查询,state,文档,match,key,es
来源: https://www.cnblogs.com/ltyc/p/16220873.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有