弹性搜索ElasticSearch安装及基础入门教程


本博文仅供记录笔记,博文记录得不是很全,详情请移步至《ElasticSearch官方文档》。小编初次接触Elastic,若有什么写得不对的地方欢迎各位大佬留言。

简介

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。

一、安装

1. 下载Elastic

提前:Elastic需要 Java 8 环境。如果你的机器还没安装 Java,请先安装JDK,注意要保证环境变量JAVA_HOME正确设置。

安装完 Java,就可以跟着官方文档安装 Elastic。直接下载压缩包比较简单。

Elastic可跨平台使用,小编这里就以Windows为例。

下载地址:Elastic官网下载

如图点击即可下载(这里下载的是压缩包):

Elastic官网下载小编下载的版本是7.7.1,现在官网已经更新到7.8.0了。

2. 解压Elastic

解压此压缩包到指定目录,打开./elasticsearch-7.7.1,目录结构如下:
在这里插入图片描述

  • bin:脚本文件,里面包括启动elasticSearch,安装插件等。
  • config:配置文件目录,里面有个很重要的配置文件elasticsearch.yml
  • data:数据文件
  • jdk:java运行环境
  • lib:java类库
  • logs:日志文件
  • modules:包含所有的es模块
  • plugins:包含所有已经安装的插件

2. 启动Elastic

进入./elasticsearch-7.7.1/bin,Windows下双击运行elasticsearch.bat脚本文件即可启动Elastic。

Linux下命令启动:

./elasticsearch

如果这时报错"max virtual memory areas vm.maxmapcount [65530] is too low",要运行下面的命令:

sudo sysctl -w vm.max_map_count=262144

如果一切正常,Elastic 就会在默认的9200端口运行。可通过postman发送GET请求,会得到说明信息
RQ:

GET localhost:9200

RS:

{
  "name": "DESKTOP-CYK",
  "cluster_name": "elasticsearch",
  "cluster_uuid": "8qzW6nfoTAa7-YtloNrXew",
  "version": {
    "number": "7.7.1",
    "build_flavor": "default",
    "build_type": "zip",
    "build_hash": "ad56dce891c901a492bb1ee393f12dfff473a423",
    "build_date": "2020-05-28T16:30:01.040088Z",
    "build_snapshot": false,
    "lucene_version": "8.5.1",
    "minimum_wire_compatibility_version": "6.8.0",
    "minimum_index_compatibility_version": "6.0.0-beta1"
  },
  "tagline": "You Know, for Search"
}

上面RS中,请求9200端口,Elastic 返回一个 JSON 对象,包含当前节点、集群、版本等信息。

默认情况下,Elastic 只允许本机访问,如果需要远程访问,可以修改 Elastic 安装目录的config/elasticsearch.yml文件,去掉network.host的注释,将它的值改成0.0.0.0,然后重新启动 Elastic。

network.host: 0.0.0.0

上面代码中,设成0.0.0.0让任何人都可以访问。线上服务不要这样设置,要设成具体的 IP,并加上cluster.initial_master_nodes: ["node-name"]

二、基本概念

1. 节点(Node)与集群(Cluster)

Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。

单个 Elastic 实例称为一个节点(node)。一组节点构成一个集群(cluster)。

2. 索引(Index)

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

所以,Elastic 数据管理的顶层单位就叫做 Index(索引)。它可看作是单个数据库。每个 Index 的名字必须是小写。

下面的请求可以查看当前节点的所有 Index。
RQ:

GET localhost:9200/_cat/indices?v

RS:

health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   school Hlo2I4KlQU-uLqjw-lDq6g   1   1          2            1     11.7kb         11.7kb

上述RS中有一个索引school

3. 文档(Document)

Index 里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。

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

{
  "id": "1",
  "name": "成应奎",
  "age": 24,
  "desc": "我是一名三好学生"
}

同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。

4. 类型(Type)

Document 可以分组,比如school这个Index 里面,可以按教师分组,也可以按学生分组。这种分组就叫做 Type,它是虚拟的逻辑分组,用来过滤 Document。

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

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

GET localhost:9200/_mapping?pretty=true

RS:

{
  "school": {
    "mappings": {}
  }
}

根据elastic官网规划,Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type。

三、Index操作

1. 添加 Index

向Elastic服务器发送PUT请求:
RQ:

PUT localhost:9200/school

RS:

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

服务器返回一个 JSON 对象,里面的acknowledged字段为true表示添加成功。

2. 查看 Index

向Elastic服务器发送GET请求:
RQ:查看school这个Index

GET localhost:9200/school

RS:

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

RQ:查看当前实例中所有Index

GET localhost:9200/_cat/indices?v

RS:

health status index  uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   school XllA1jp4T9epF39e9uPwkw   1   1          0            0       208b           208b

3. 删除 Index

向Elastic服务器发送DELETE请求:
RQ:

DELETE localhost:9200/school

RS:

{
    "acknowledged": true
}

三、数据操作

1. 添加数据

向Elastic服务器发送PUT请求,添加一条student数据,有id、name、age、desc四个属性:

{
  "id": "1",
  "name": "成应奎",
  "age": 24,
  "desc": "我是一名三好学生"
}

该数据在school这个Index下,属于student这个Type,student的属性数据就是document,即请求模板为localhost:9200/index/type/{id}
RQ:

PUT localhost:9200/school/student/1

{
    "name": "成应奎",
    "age": 24,
    "desc": "我是一名三好学生"
}

RS:

{
    "_index": "school",
    "_type": "student",
    "_id": "1",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 1
}

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

如果你仔细看,会发现请求路径是/school/student/1,最后的1是该条记录的 id。它不一定是数字,任意字符串(比如abc)都可以。

新增记录的时候,也可以不指定 id,但是这时要改成 POST 请求。
RQ:

POST localhost:9200/school/student

{
    "name": "张三",
    "age": 25,
    "desc": "我是一名班级干部"
}

RS:

{
    "_index": "school",
    "_type": "student",
    "_id": "EYamPXMBSJB2se0qHXyl",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 1,
    "_primary_term": 1
}

这时,服务器返回的 JSON 对象里面,_id字段就是一个随机字符串。

注意,如果没有先创建 Index(这个例子是school),直接执行上面的命令,Elastic 也不会报错,而是直接生成指定的 Index。所以,打字的时候要小心,不要写错 Index 的名称。

2. 查看数据

向Elastic服务器发送GET请求:
RQ:

GET localhost:9200/school/student/1?pretty=true

RS:

{
    "_index": "school",
    "_type": "student",
    "_id": "1",
    "_version": 1,
    "_seq_no": 0,
    "_primary_term": 1,
    "found": true,
    "_source": {
        "name": "成应奎",
        "age": 24,
        "desc": "我是一名三好学生"
    }
}

上面RQ代码中请求查看/school/student/1这条记录,URL 的参数pretty=true表示以易读的格式返回。

返回的数据RS中,found字段为true表示查询成功,_source字段返回数据记录。

如果id不正确,就查不到数据,found字段就是false。例如下面的请求:
RQ:

GET localhost:9200/school/student/abc?pretty=true

RS:

{
  "_index": "school",
  "_type": "student",
  "_id": "abc",
  "found": false
}

3. 删除数据

向Elastic服务器发送DELETE请求:
RQ:

DELETE localhost:9200/school/student/1

RS:

{
    "_index": "school",
    "_type": "student",
    "_id": "1",
    "_version": 2,
    "result": "deleted",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 2,
    "_primary_term": 1
}

这里先不要删除这条记录,后面还要用到。

4. 更新数据

更新记录就是使用 PUT 请求,重新发送一次数据:
RQ:

PUT localhost:9200/school/student/1

{
    "name": "成应奎",
    "age": 24,
    "desc": "我是一名三好学生也是一名班级干部"
}

RS:

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

上面RQ代码中,小编将原始数据从"我是一名三好学生“改成”我是一名三好学生也是一名班级干部"。 返回结果里面,有几个字段发生了变化。

可以看到,记录的 id 没变,但是版本(version)从1变成2,操作结果(result)从created变成updated

在低版本的Elastic中更新操作返回的JSON里面有一个created字段变成false,因为这次不是新建记录。高版本的Elastic中删除了created字段。

四、数据查询

1. 查询所有数据

向Elastic服务器发送GET请求:
RQ:

GET localhost:9200/school/student/_search

RS:

{
    "took": 62,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "school",
                "_type": "student",
                "_id": "EYamPXMBSJB2se0qHXyl",
                "_score": 1.0,
                "_source": {
                    "name": "张三",
                    "age": 25,
                    "desc": "我是一名班级干部"
                }
            },
            {
                "_index": "school",
                "_type": "student",
                "_id": "1",
                "_score": 1.0,
                "_source": {
                    "name": "成应奎",
                    "age": 24,
                    "desc": "我是一名三好学生也是一名班级干部"
                }
            }
        ]
    }
}

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

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

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

2. 全文搜索

Elastic 的查询要求 GET 请求带有数据体,更多请查看官方文档-全文查询

2.1 Match 查询

RQ:Match 查询,指定的匹配条件是desc字段里面包含"三好学生"这个词。

GET localhost:9200/school/student/_search

{
    "query": {
        "match": {
            "desc": "三好学生"
        }
    }
}

RS:

{
    "took": 28,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.5607667,
        "hits": [
            {
                "_index": "school",
                "_type": "student",
                "_id": "1",
                "_score": 1.5607667,
                "_source": {
                    "name": "成应奎",
                    "age": 24,
                    "desc": "我是一名三好学生也是一名班级干部"
                }
            }
        ]
    }
}

Elastic 默认一次返回10条结果,可以通过size字段改变这个设置。

{
    "query": {
        "match": {
            "desc": "三好学生"
        }
    },
    "size": 5
}

还可以通过from字段,指定位移。

{
    "query": {
        "match": {
            "desc": "三好学生"
        }
    },
    "from": 1,
    "size": 5
}

fromsize一起使用即为分页查询,上述代码中从位置1开始(默认是从位置0开始),只返回5条结果。

3. 逻辑运算

3.1 OR运算

如果有多个搜索关键字, Elastic 认为它们是or关系。

RQ:

GET localhost:9200/school/student/_search

{
    "query": {
        "match": {
            "desc": "学生 干部"
        }
    }
}

RS:

{
    "took": 8,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.5607667,
        "hits": [
            {
                "_index": "school",
                "_type": "student",
                "_id": "1",
                "_score": 1.5607667,
                "_source": {
                    "name": "成应奎",
                    "age": 24,
                    "desc": "我是一名三好学生也是一名班级干部"
                }
            },
            {
                "_index": "school",
                "_type": "student",
                "_id": "EYamPXMBSJB2se0qHXyl",
                "_score": 1.0470967,
                "_source": {
                    "name": "张三",
                    "age": 25,
                    "desc": "我是一名班级干部"
                }
            }
        ]
    }
}

上面RQ代码中搜索的是学生 or 干部,中间有一个空格隔开。

下面这段RQ代码没有空格隔开也能查出两条数据:

RQ:

GET localhost:9200/school/student/_search

{
    "query": {
        "match": {
            "desc": "学生干部"
        }
    }
}

RS:

{
    "took": 8,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1.5607667,
        "hits": [
            {
                "_index": "school",
                "_type": "student",
                "_id": "1",
                "_score": 1.5607667,
                "_source": {
                    "name": "成应奎",
                    "age": 24,
                    "desc": "我是一名三好学生也是一名班级干部"
                }
            },
            {
                "_index": "school",
                "_type": "student",
                "_id": "EYamPXMBSJB2se0qHXyl",
                "_score": 1.0470967,
                "_source": {
                    "name": "张三",
                    "age": 25,
                    "desc": "我是一名班级干部"
                }
            }
        ]
    }
}

这里就是分词查询出来的结果,Elastic会将学生干部分为若干个分词进行查询,其中就分为学生 or 干部

3.2 AND运算

如果要执行多个关键词的and搜索,必须使用布尔查询

RQ:

GET localhost:9200/school/student/_search

{
  "query": {
    "bool": {
      "must": [
        { "match": { "desc": "学生" } },
        { "match": { "desc": "干部" } }
      ]
    }
  }
}

RS:

{
    "took": 15,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.5607667,
        "hits": [
            {
                "_index": "school",
                "_type": "student",
                "_id": "1",
                "_score": 1.5607667,
                "_source": {
                    "name": "成应奎",
                    "age": 24,
                    "desc": "我是一名三好学生也是一名班级干部"
                }
            }
        ]
    }
}

上面RQ代码中搜索的是学生 and 干部,所以查询出来的结果只有一条数据。

五、官方文档

ElasticSearch官方文档

本博文仅供记录笔记,博文记录得不是很全,详情请移步至《ElasticSearch官方文档》。小编初次接触Elastic,若有什么写得不对的地方欢迎各位大佬留言。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值