Elasticsearch学习笔记(入个门)

Elasticsearch学习笔记(入个门)

7.2.0版本

Elasticsearch安装启动

单实例

跟大部分开源产品一样,下载一个压缩包,解压缩就可用了。

解压后的文件目录说明

Elasticsearch学习笔记(入个门)

启动

bin/elasticsearch -E node.name=node1 -E cluster.name=ljktest -E path.data=node1_data

验证

浏览器输入localhost:9200

{
    "name": "node1",
    "cluster_name": "ljktest",
    "cluster_uuid": "iX1RgTXYRUWIqe9CucwQrA",
    "version": {
        "number": "7.2.0",
        "build_flavor": "default",
        "build_type": "tar",
        "build_hash": "508c38a",
        "build_date": "2019-06-20T15:54:18.811730Z",
        "build_snapshot": false,
        "lucene_version": "8.0.0",
        "minimum_wire_compatibility_version": "6.8.0",
        "minimum_index_compatibility_version": "6.0.0-beta1"
    },
    "tagline": "You Know, for Search"
}

到此安装成功了

安装插件icu

bin/elasticsearch-plugin install analysis-icu

查看安装插件

bin/elasticsearch-plugin list

多实例集群

bin/elasticsearch -E node.name=node1 -E cluster.name=ljktest -E path.data=node1_data -d
bin/elasticsearch -E node.name=node2 -E cluster.name=ljktest -E path.data=node2_data -d
bin/elasticsearch -E node.name=node3 -E cluster.name=ljktest -E path.data=node3_data -d

查看集群节点信息

http://localhost:9200/_cat/nodes?v

ip        heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
127.0.0.1           34         100  48    4.22                  mdi       -      node3
127.0.0.1           26         100  27    4.22                  mdi       *      node1
127.0.0.1           23         100  27    4.22                  mdi       -      node2

使用RestApi与集群交互

你能够通过API做到

  1. 检查群集,节点和索引运行状况,状态和统计信息
  2. 管理您的群集,节点和索引数据和元数据
  3. 对索引执行CRUD(创建,读取,更新和删除)和搜索操作
  4. 执行高级搜索操作,例如分页,排序,过滤,脚本编写,聚合等等

集群健康状态检查

GET /_cat/health?v

epoch      timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1563931882 01:31:22  ljktest green           2         2      4   2    0    0        0             0                  -                100.0%

集群健康表示为三个颜色,分别为绿色、黄色、红色。

  • 绿色 - 一切都很好(集群功能齐全)
  • 黄色 - 所有数据都可用,但尚未分配一些副本(群集功能齐全)
  • 红色 - 某些数据由于某种原因不可用(群集部分功能)

注意:当群集为红色时,它将继续提供来自可用分片的搜索请求,但您可能需要尽快修复它,因为存在未分配的分片。

列出所有索引

GET /_cat/indices?v

health status index                uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   .kibana_task_manager VzO_iN_ZS1qfEIcAdppCtQ   1   1          2            0     25.5kb         12.7kb
green  open   .kibana_1            HC1uWncjT_qYh2oX_cqk7g   1   1          4            0     30.8kb         15.4kb

创建一个索引

PUT /customer?pretty

{
    "acknowledged": true,
    "shards_acknowledged": true,
    "index": "customer"
}

给索引添加文档

PUT /customer/_doc/1?pretty
{
  "name": "John Doe"
}
{
    "_index": "customer",
    "_type": "_doc",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 2,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

注意:Elasticsearch不需要在将文档编入索引之前先显式创建索引。在前面的示例中,如果客户索引事先尚未存在,则Elasticsearch将自动创建客户索引。

查询文档

GET /customer/_doc/1?pretty

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

除了字段之外,没有任何异常,发现,声明我们找到了一个具有请求ID 1的文档和另一个字段_source,它返回我们从上一步索引的完整JSON文档。

删除索引

DELETE /customer?pretty

{
    "acknowledged": true
}

修改文档

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

改变ID1文档的name属性

PUT /customer/_doc/1?pretty
{
  "name": "Jane Doe"
}

增加一个ID2的文档

PUT /customer/_doc/2?pretty
{
  "name": "Jane Doe"
}

索引时,ID部分是可选的。如果未指定,Elasticsearch将生成随机ID,然后使用它来索引文档。Elasticsearch生成的实际ID(或前面示例中显式指定的内容)将作为索引API调用的一部分返回。

POST /customer/_doc?pretty
{
  "name": "Jane Doe"
}
{
    "_index": "customer",
    "_type": "_doc",
    "_id": "tUsLImwBpPtD8mF4h9JJ",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 2,
        "failed": 0
    },
    "_seq_no": 1,
    "_primary_term": 1
}

更新文档

除了能够索引和替换文档,我们还可以更新文档。请注意,Elasticsearch实际上并没有在引擎盖下进行就地更新。每当我们进行更新时,Elasticsearch都会删除旧文档,然后一次性对应用了更新的新文档编制索引。

  • 更改名称
POST /customer/_update/1?pretty
{
  "doc": { "name": "Jane Doe" }
}
  • 增加年龄
POST /customer/_update/1?pretty
{
  "doc": { "name": "Jane Doe", "age": 20 }
}
  • 使用脚本更新年龄+5
POST /customer/_update/1?pretty
{
  "script" : "ctx._source.age += 5"
}

批量执行

除了能够索引,更新和删除单个文档之外,Elasticsearch还提供了使用_bulk API批量执行上述任何操作的功能。此功能非常重要,因为它提供了一种非常有效的机制,可以尽可能快地进行多个操作,并尽可能少地进行网络往返。

Bulk API不会因其中一个操作失败而失败。如果单个操作因任何原因失败,它将继续处理其后的其余操作。批量API返回时,它将为每个操作提供一个状态(按照发送的顺序),以便您可以检查特定操作是否失败。

POST /customer/_bulk?pretty
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }

此示例更新第一个文档(ID为1),然后在一个批量操作中删除第二个文档(ID为2):

POST /customer/_bulk?pretty
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}

Search API

导入一些测试数据

测试数据格式

{
    "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"
}

导入

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

查询所有数据

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

分页查询

from参数(从0开始)指定从哪个文档索引开始,size参数指定从from参数开始返回的文档数。在实现搜索结果的分页时,此功能非常有用。请注意,如果未指定from,则默认为0。size默认为10。

GET /bank/_search
{
  "query": { "match_all": {} },
  "from": 10,
  "size": 5
}

只返回感兴趣的字段

GET /bank/_search
{
  "query": { "match_all": {} },
  "_source": ["account_number", "balance"]
}

过滤请求

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

OR 和 AND

此示例返回地址中包含术语“mill”或“lane”的所有帐户

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

此示例是match(match_phrase)的变体,它返回地址中包含短语“mill lane”的所有帐户

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

bool query

此示例组成两个匹配查询,并返回地址中包含“mill”和“lane”的所有帐户。等价于上面的AND。

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

相反,此示例组成两个匹配查询并返回地址中包含“mill”或“lane”的所有帐户,等价于上面的OR

GET /bank/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

我们可以在bool查询中同时组合must,should和must_not子句。此外,我们可以在任何这些bool子句中组合bool查询来模仿任何复杂的多级布尔逻辑。

Range查询

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

聚合

首先,此示例按状态对所有帐户进行分组,然后返回按计数降序排序的前10个(默认)状态(也是默认值)

请注意,我们将size = 0设置为不显示搜索匹配,因为我们只想在响应中看到聚合结果。

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

在前一个聚合的基础上,此示例按州计算平均帐户余额(同样仅针对按降序排序的前10个州)

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

这个例子演示了我们如何按年龄段(20-29岁,30-39岁和40-49岁),然后按性别分组,最后得到每个年龄段的平均账户余额,每个年龄段

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 20,
            "to": 30
          },
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "group_by_gender": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "average_balance": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}

附录