Elasticsearch教程

Elasticsearch教程TabTan

这篇笔记记录于2021年8月,一些基本操作。迁移至此,分享给需要它的人。


快速开始

索引

员工案例
保存

对于员工目录,我们将做如下操作:

  • 每个员工索引一个文档,文档包含该员工的所有信息。
  • 每个文档都将是 employee 类型
  • 该类型位于 索引 megacorp 内。
  • 该索引保存在我们的 Elasticsearch 集群中。

实践中这非常简单(尽管看起来有很多步骤),我们可以通过一条命令完成所有这些动作:

PUT /megacorp/employee/1
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}
curl -X PUT "101.201.125.13:9200/test/user/1?pretty" -H 'Content-Type: application/json' -d'
{
    "first_name" : "三",
    "last_name" :  "唐",
    "age" :        25,
    "about" :      "佛祖有泪 观音泪",
    "interests": [ "Rap", "music" ]
}
'

注意,路径 /megacorp/employee/1 包含了三部分的信息:

  • megacorp

    索引名称

  • employee

    类型名称

  • 1

    特定雇员的ID

索引文档
GET /megacorp/employee/1
curl -X GET "localhost:9200/megacorp/employee/1?pretty"

在这里插入图片描述

将 HTTP 命令由 PUT 改为 GET 可以用来检索文档,同样的,可以使用 DELETE 命令来删除文档,以及使用 HEAD 指令来检查文档是否存在。如果想更新已存在的文档,只需再次 PUT

轻量搜索

索引全部
GET /megacorp/employee/_search
curl -X GET "localhost:9200/megacorp/employee/_search?pretty"

在这里插入图片描述

索引带条件

GET /megacorp/employee/_search?q=last_name:唐

# or

curl -X GET "localhost:9200/megacorp/employee/_search?q=last_name:Smith&pretty"

在这里插入图片描述

_search表示轻量索引,q=表示索引条件

查询表达式搜索

Query-string 搜索通过命令非常方便地进行临时性的即席搜索 ,但它有自身的局限性(参见 轻量 搜索 )。Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 它支持构建更加复杂和健壮的查询。

GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}
# or for curl
curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}
'

返回结果与之前的查询一样,但还是可以看到有一些变化。其中之一是,不再使用 query-string 参数,而是一个请求体替代。这个请求使用 JSON 构造,并使用了一个 match 查询(属于查询类型之一,后面将继续介绍)。

复杂搜索

现在尝试下更复杂的搜索。 同样搜索姓氏为 唐 的员工,但这次我们只需要年龄大于 18 的。查询需要稍作调整,使用过滤器 filter ,它支持高效地执行一个结构化查询。

GET /megacorp/employee/_search
{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "last_name" : "唐" 
                }
            },
            "filter": {
                "range" : {
                    "age" : { "gt" : 18 } 
                }
            }
        }
    }
}
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.24116206,
    "hits" : [
      {
        "_index" : "megacorp",
        "_type" : "employee",
        "_id" : "3",
        "_score" : 0.24116206,
        "_source" : {
          "first_name" : "三藏",
          "last_name" : "唐",
          "age" : 42,
          "about" : "观音我来了 阿弥陀佛",
          "interests" : [
            "forestry"
          ]
        }
      }
    ]
  }
}

全文搜索

GET /megacorp/employee/_search
{
  "query":{
    "match": {
      "first_name": "三"
    }
  }
}

根据匹配度排序的全文查询

短语搜索

match_phrase
GET /megacorp/employee/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "三"
        }
    }
}

100%匹配 所有短语中存在三的才行

高亮搜索

许多应用都倾向于在每个搜索结果中 高亮 部分文本片段,以便让用户知道为何该文档符合查询条件。在 Elasticsearch 中检索出高亮片段也很容易。

再次执行前面的查询,并增加一个新的 highlight 参数:

GET /megacorp/employee/_search
{
    "query" : {
        "match_phrase" : {
            "first_name" : "三"
        }
    },
    "highlight": {
        "fields" : {
            "first_name" : {}
        }
    }
}

当执行该查询时,返回结果与之前一样,与此同时结果中还多了一个叫做 highlight 的部分。这个部分包含了 about 属性匹配的文本片段,并以 HTML 标签 <em></em> 封装:
在这里插入图片描述

分析

终于到了最后一个业务需求:支持管理者对员工目录做分析。 Elasticsearch 有一个功能叫聚合(aggregations),允许我们基于数据生成一些精细的分析结果。聚合与 SQL 中的 GROUP BY 类似但更强大。

字段优化
# 字段优化
PUT /megacorp/employee/_mapping?include_type_name=true
{
  "properties": {
    "interests": { 
      "type":     "text",
      "fielddata": true
    }
  }
}
聚合索引
GET /megacorp/employee/_search
{
  "aggs": {
    "all_interests": {
      "terms": { "field": "interests" }
    }
  }
}

{
  "took" : 163,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "megacorp",
        "_type" : "employee",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "first_name" : "培正",
          "last_name" : "谈",
          "age" : 18,
          "about" : "不要迷恋哥 哥只是个传说",
          "interests" : [
            "唱",
            "Rap",
            "跳",
            "篮球"
          ]
        }
      },
      {
        "_index" : "megacorp",
        "_type" : "employee",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "first_name" : "三",
          "last_name" : "唐",
          "age" : 16,
          "about" : "观音有泪",
          "interests" : [
            "forestry"
          ]
        }
      },
      {
        "_index" : "megacorp",
        "_type" : "employee",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "first_name" : "三藏",
          "last_name" : "唐",
          "age" : 42,
          "about" : "观音我来了 阿弥陀佛",
          "interests" : [
            "forestry"
          ]
        }
      }
    ]
  },
  "aggregations" : {
    "all_interests" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "forestry",
          "doc_count" : 2
        },
        {
          "key" : "rap",
          "doc_count" : 1
        },
        {
          "key" : "唱",
          "doc_count" : 1
        },
        {
          "key" : "球",
          "doc_count" : 1
        },
        {
          "key" : "篮",
          "doc_count" : 1
        },
        {
          "key" : "跳",
          "doc_count" : 1
        }
      ]
    }
  }
}

集群

集群健康

GET /_cluster/health
{
  "cluster_name" : "docker-cluster",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 10,
  "active_shards" : 10,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 1,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 90.9090909090909
}

status 字段指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:

green所有的主分片和副本分片都正常运行。

yellow所有的主分片都正常运行,但不是所有的副本分片都正常运行。

red有主分片没能正常运行。在本章节剩余的部分,我们将解释什么是 分片和 副本 分片,以及上面提到的这些颜色的实际意义。

分片

PUT /blogs
{
   "settings" : {
      "number_of_shards" : 2,
      "number_of_replicas" : 1
   }
}

创建了一个blogs索引,其中包含2个主分片,每个主分片包含一个副本分片

集群的健康状况为 yellow 则表示全部 分片都正常运行(集群可以正常服务所有请求),但是 副本 分片没有全部处在正常状态。 实际上,所有3个副本分片都是 unassigned —— 它们都没有被分配到任何节点。 在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。

当前我们的集群是正常运行的,但是在硬件故障时有丢失数据的风险。

更多扩容

在运行中的集群上是可以动态调整副本分片数目的,我们可以按需伸缩集群。让我们把副本数从默认的 1 增加到 2

PUT /blogs/_settings
{
   "number_of_replicas" : 2
}

语法

只搜索部分

GET /megacorp/employee/1?_source=first_name
{
  "_index" : "megacorp",
  "_type" : "employee",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "first_name" : "培正"
  }
}
  • /_search

    在所有的索引中搜索所有的类型

  • /gb/_search

    gb 索引中搜索所有的类型

  • /gb,us/_search

    gbus 索引中搜索所有的文档

  • /g*,u*/_search

    在任何以 g 或者 u 开头的索引中搜索所有的类型

  • /gb/user/_search

    gb 索引中搜索 user 类型

  • /gb,us/user,tweet/_search

    gbus 索引中搜索 usertweet 类型

  • /_all/user,tweet/_search

    在所有的索引中搜索 usertweet 类型

当在单一的索引下进行搜索的时候,Elasticsearch 转发请求到索引的每个分片中,可以是主分片也可以是副本分片,然后从每个分片中收集结果。多索引搜索恰好也是用相同的方式工作的—只是会涉及到更多的分片。

分页

SQL 使用 LIMIT 关键字返回单个 page 结果的方法相同,Elasticsearch 接受 fromsize 参数:

  • size

    显示应该返回的结果数量,默认是 10

  • from

    显示应该跳过的初始结果数量,默认是 0

GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10
# or for curl
curl -X GET "localhost:9200/_search?size=5&pretty"
curl -X GET "localhost:9200/_search?size=5&from=5&pretty"
curl -X GET "localhost:9200/_search?size=5&from=10&pretty"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值