关于 Elasticsearch 你想知道的

一、ElasticSearch 简介

持续更新

ElasticSearch 是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据,本身扩展性很好,可以扩展上百台服务器,处理 PB 级别数据。

Elasticsearch 也可以使用 Java 开发并使用 Lucene 作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTFUL API 来隐藏 lucence 的复杂性,从而让全文搜索变得简单。

二、Docker 安装 Elasticsearch

docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -d elasticsearch:7.16.2

安装中文分词器

方法一:

1. 进入容器
docker exec -it elasticsearch bash

2. 进入plugins 目录
cd /usr/share/elasticsearch/plugins

3. 安装中文分词器
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.16.2/elasticsearch-analysis-ik-7.16.2.zip

4. 退出容器重启 elasticsearch
docker restart elasticsearch 

方法二:
前往这里下载对应版本的 ik 分词器,进入容器

# 1. 复制ik分词器到容器内
docker cp elasticsearch-analysis-ik-7.16.2.zip 7c0ae984c060:/usr/share/elasticsearch/plugins
# 2. 进入容器
docker exec -it elasticsearch bash

# 3. 进入plugins 目录
cd /usr/share/elasticsearch/plugins

# 4. 新建 ik 文件夹解压进去
mkdir ik
unzip elasticsearch-analysis-ik-7.16.2.zip -d ./ik

# 5. 删除 elasticsearch-analysis-ik-7.16.2.zip
rm -rf elasticsearch-analysis-ik-7.16.2.zip

# 6. 退出容器重启 elasticsearch
docker restart elasticsearch 

三、基本概念

  1. Cluster 集群与 Node 节点

    ES 可以作为一个单独的搜索服务器,不过,为了处理大量数据,实现容错和高可用性,ES 可以运行在许多互相合作的服务器上,这些服务器的集合称为集群。每一个组成的服务器称为一个节点(node)。

  2. Shard 分片

    当有大量文档时,由于内存的限制,磁盘处理能力不足。无法足够快的响应客户的请求,一个节点不够用,这时,数据可以分为较小的分片,每个分片放到不同的服务器上。当你查询的索引分布在多个分片上时,ES 会把查询发送到每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。

  3. Index

    ES 会索引所有字段,经过处理后写入到一个反向索引(Inverted Index)。查找数据的时候直接查询该索引。

    所以,ES 数据管理的顶层单位就叫做 Index(索引)。它是单个数据库的同义词,每个 Index(即数据库)的名字必须是小写。

    下面的命令是查看当前节点的所有 Index

    curl -X GET 'http://localhost:9200/_cat/indices?v'
    
  4. Document

    Index 里面单条记录称为 Docment(文档),许多条文档构成了 Index。

    Document 使用 JSON 格式表示,下面是一个例子。

    {
      "user": "sixkery",
      "title": "es",
      "desc": "分布式搜索引擎"
    }
    
  5. Type(可不看)

    Document 可以分组,比如weather这个 Index 里面,可以按城市分组(北京和上海),也可以按气候分组(晴天和雨天)。这种分组就叫做 Type,它是虚拟的逻辑分组,用来过滤 Document。

    不同的 Type 应该有相似的结构(schema),举例来说,id字段不能在这个组是字符串,在另一个组是数值。这是与关系型数据库的表的一个区别。性质完全不同的数据(比如productslogs)应该存成两个 Index,而不是一个 Index 里面的两个 Type(虽然可以做到)。

    下面的命令可以列出每个 Index 所包含的 Type。

    $ curl 'http://localhost:9200/_mapping?pretty=true'
    

    根据规划,Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type,提供一个默认的 type 是 _doc。

四、新建和删除 Index

新建 Index,可以直接向 ES 发送 PUT 请求,比如新建 userInfo 的索引。

curl -X PUT 'http://localhost:9200/userInfo'

服务器返回一个 JSON 对象,里面的acknowledged字段表示操作成功。

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

然后发送 delete 请求,删除这个索引

curl -X DELETE 'http://localhost:9200/userInfo'

五、新建索引

新建一个指定中文分词器的索引,这里需要指定分词的字段,基本上,凡是需要搜索的中文字段,都需要设置一下。

curl -X PUT 'http://localhost:9200/accounts' \
--header 'Content-Type: application/json' \
--data-raw '{
    "mappings": {
        "properties": {
            "user": {
                "type": "text",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word"
            },
            "title": {
                "type": "text",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word"
            },
            "desc": {
                "type": "text",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word"
            }
        }
    }
}'

上面代码中创建了一个名为 accounts 的索引,有三个字段:user 、title、desc。这三个字段都是中文,而且类型都是文本(text),所以需要指定中文分词器,不能使用默认的英文分词器。

"user": {
    "type": "text",
    "analyzer": "ik_max_word",
    "search_analyzer": "ik_max_word"
},
# 这里 analyzer 是字段文本的分词器,search_analyzer 是搜索词的分词器。ik_max_word 分词器是插件 ik 提供的,可以对文本进行最大数量的分词。

六、数据操作

6.1 新增数据

向指定索引发送 POST 请求就可以在 Index 中新增数据。

curl -X POST 'http://localhost:9200/accounts/_doc' \
--header 'Content-Type: application/json' \
--data-raw '{
    "user": "sixkery",
    "title": "es工程师",
    "desc": "代码写的好"
}'

服务器返回的 JSON 对象,会给出 Index、Type、Id、Version 等信息。

{
    "_index": "accounts",
    "_type": "_doc",
    "_id": "-xxs0H8B-7-agoquNFaJ",
    "_version": 1,
    "result": "created",
    "_shards": { "total": 2, "successful": 1, "failed": 0 },
    "_seq_no": 0,
    "_primary_term": 1
}

上面没有指定数据的 _id ,es 会自动生成一个随机的字符串。如果指定数据的 _id 的话可以发送 put 请求

curl --location --request PUT 'http://localhost:9200/accounts/_doc/1' \
--header 'Content-Type: application/json' \
--data-raw '{
    "user": "果果",
    "title": "捣蛋猫",
    "desc": "猫粮快拿来"
}'
6.2 查看数据

向索引发送 GET 请求,就可以查看这条数据:

curl -X GET 'http://localhost:9200/accounts/_doc/1?pretty=true'
{
  "_index" : "accounts",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 1,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "user" : "果果",
    "title" : "捣蛋猫",
    "desc" : "猫粮快拿来"
  }
}

url 请求查看索引 accounts id 为 1 的数据,参数 pretty=true 表示以易读的方式返回。返回的数据中 found 表示查询成功,_source字段返回原始记录。

6.3 更新记录

更新记录就是使用 PUT 请求,重新发送一次数据。从返回的数据中发现,记录的 Id 没变,但是版本(version)从1变成2,操作类型(result)从created变成updated,因为这次不是新建记录

curl --location --request PUT 'http://localhost:9200/accounts/_doc/1' \
--header 'Content-Type: application/json' \
--data-raw '{
    "user": "果果",
    "title": "捣蛋猫",
    "desc": "猫粮快拿来,这是更新数据"
}'

{
  "_index":"accounts",
  "_type":"_doc",
  "_id":"1",
  "_version":2,
  "result":"updated",
  "_shards":{"total":2,"successful":1,"failed":0},
  "_seq_no":2,
  "_primary_term":1
}

七、查询

7.1 查询所有记录

使用 GET 方法,直接请求/Index/Type/_search,就会返回所有记录。

curl -X GET 'http://localhost:9200/accounts/_doc/_search?pretty=true'
{
    "took": 32,
    "timed_out": false,
    "_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},
    "hits": {
        "total": {"value": 2,"relation": "eq"},
        "max_score": 1.0,
        "hits": [
            {
                "_index": "accounts",
                "_type": "_doc",
                "_id": "-xxs0H8B-7-agoquNFaJ",
                "_score": 1.0,
                "_source": {"user": "sixkery","title": "es工程师","desc": "代码写的好"}
            },
            {
                "_index": "accounts",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.0,
                "_source": {"user": "果果","title": "捣蛋猫","desc": "猫粮快拿来,这是更新数据"}
            }
        ]
    }
}

上面代码中,返回结果的 took字段表示该操作的耗时(单位为毫秒),timed_out字段表示是否超时,hits字段表示命中的记录,里面子字段的含义如下。

  • total:返回记录数,本例是2条。
  • max_score:最高的匹配程度,本例是1.0
  • hits:返回的记录组成的数组。

返回的记录中,每条记录都有一个_score字段,表示匹配的程序,默认是按照这个字段降序排列。

7.2 全文检索

感谢阮一峰博客。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值