ElasticSearch入门详解(结合Kibana)

前言

ElasticSearch是基于java的开源分布式搜索引擎,由于其强大的检索性能和较好的封装性(对lunece),给用户提供了简单易上手的API操作,也成为当前各大企业和大厂用于搜索引擎的工具。本文将对ElasticSearch的使用和入门进行详细的讲解,并结合Kibana进行部分案例的演示,希望可以让各位读者有所收获。想要获取更多有关ElasticStack其他成员的使用,可以关注本文集的其他文章。

一、应用安装

(一)安装ElasticSearch

1. 去官网下载解压包:https://www.elastic.co/downloads/elasticsearch


2. 解压和使用
将压缩包解压到指定路径后,进入bin目录执行elasticsearch.bat即可启动

注意:

  • ElasticSearch依赖于jdk环境,要求本地的jdk版本最低为jdk1.8!
  • ElasticSearch官网可能进不去,有需要的话可以从文章中获取百度网盘链接

(二)安装Kibana

  1. 进入官网下载:https://www.elastic.co/cn/kibana
  2. 解压和使用
    将压缩包解压后,进入bin目录执行kibana.bat即可

    如果对应的elasticsearch服务不在默认的端口和ip,则需要进入到config目录中,在kibana.yml文件中添加对应的配置
elasticsearch.hosts: ["http://localhost:9200"]
# 要修改启动kibana的端口的话,可以修改下面的配置
server.port: 5601

(三)安装elasticsearch-head插件

elasticsearch-head将是一款专门针对于elasticsearch的客户端工具,我们可以通过这个可视化工具来便捷地查看当前es集群的各种信息。

  1. 下载地址:https://github.com/mobz/elasticsearch-head
  2. 解压和安装
    elasticsearch-head依赖于node.js,我们需要提前准备好相关的环境,解压后进入主目录执行下面的命令
# 下载对应前端依赖 (如果太慢的话可以换成淘宝镜像下载,具体自行百度)
npm install 
# 启动
npm run start

由于跨域问题的存在,使用elasticsearch-head前我们需要先进入前面安装elasticsearch的目录中配置允许跨域


添加入下配置:

http.cors.enabled: true
http.cors.allow-origin: "*"

二、ES的核心概念

(一)数据类型

elasticsearch是面向文档关系行数据库,为了便于理解其相关的核心概念,我们可以将其与传统的关系型数据库进行参考,以便快速的理解核心概念的含义。

名称 含义
数据库(database) 索引(indices)
表(tables) types (慢慢被弃用)
行(rows) documents
字段(columns) fields

(二)检索方式——倒排索引

以下图为例,左侧是文章id和每篇文章对应的标签。当使用倒排索引的时候,会将标签分为两类,这样的话当我们想搜索和python相关的博客的时候,就无需搜索全部文章,而只需要从索引列表中检索即可。大大提高了检索效率。(倒排索引的核心在于分词)

三、实操——通过REST风格进行ES的CRUD操作

method url地址 描述
PUT localhost:9200/索引名称/类型名称/文档id 创建文档(指定文档id)
POST localhost:9200/索引名称/类型名称 创建文档(随机文档id)
POST localhost:9200/索引名称/类型名称/文档id/_update 修改文档
DELETE localhost:9200/索引名称/类型名称/文档id 删除文档
GET localhost:9200/索引名称/类型名称/文档id 通过文档id查询文档
POST localhost:9200/索引名称/类型名称/_search 查询所有的数据

启动ESKibana服务,进入Kibana左侧菜单栏的Dev Tool

(一)PUT 命令

1、使用es默认提供的数据类型

PUT /index_test1/_doc/1
{
  "name": "小明",
  "age": 10
}

响应结果

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

我们可以看到,通过这种方式新建的索引数据,es会默认给上对应的字段类型。如果有需要指定类型的话,需要我们进行自定义。

2、自定义索引表字段类型
2.1、字段的类型

字符串类型: text、keyword
数值类型: long、integer、short、byte、double、float、half、float、scaled、
日期类型:date
布尔值类型: boolean
二进制类型: binary

2.2、自定义索引字段类型
PUT /index_test2
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "age": {
        "type": "integer"
      }
    }
  }
}

我们可以看到自定义字段后,再次查询得到的结果就是我们定义好的类型了。


2.3、扩展命令
GET _cat/health    获取es健康值
GET _cat/indices       获取es的所有索引
2.4、索引数据修改
  • 使用PUT命令
PUT /index_test1/_doc/1
{
  "name": "小蓝"
}

响应结果如下:

{
  "_index" : "index_test1",  // 索引名称
  "_type" : "_doc",  // 索引类型
  "_id" : "1",   // 数据id
  "_version" : 2, // 版本,每修改一次数据版本+1
  "result" : "updated",  // 状态:已更新
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

我们查看数据发现,源数据确认已经修改成功,但是age字段的值却变为了空。


这是因为elasticSearch使用PUT命令进行更新的时候,对于没有赋值的字段会一律修改为空。所以一般来说,我们基本上是使用POST方法来进行更新的

POST /index_test1/_doc/1/_update
{
  "doc": {
    "name": "小蓝"
  }
}

(二)DELETE

DELETE一般用于索引的删除,使用方式也十分简单

DELETE /index_test1

(三)GET

我们可以利用GET来查看索引和文档,查询的请求头格式如下:

GET /索引/类型/文档

对于查询体,也就是查询的具体条件,es支持两种查询方式。常规的REST URI方式和REST 请求体方式

  • URI方式



    对于REST请求体方式,则在下一节进行讲解

四、关于ES多条件查询详解

1. 模糊查询(match)
GET /index_test1/_doc/_search
{
  "query": {
    "match": {
      "name": "小明"
    }
  }
}
2. 排序(sort)
GET /index_test1/_doc/_search
{
  "query": {
    "match": {
      "name": "小明"
    }
  },
  "sort": [
    {
      "age": "desc"
    }
  ]
}
3. 字段选择(source)
GET /index_test1/_doc/_search
{
  "query": {
    "match": {
      "name": "小明"
    }
  },
  "_source": ["name"]
}
4. 限制结果记录条数(from 、size)
GET /index_test1/_doc/_search
{
  "query": {
    "match": {
      "name": "小明"
    }
  },
  "from": 1, 
  "size": 1 
}
5. 条件查询(可以写多个查询条件,并进行与或非逻辑判断)
GET /index_test1/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "小明"
          }
        },
        {
          "match": {
            "age": 11
          }
        }
      ]
    }
  }
}
6. 过滤器(filter)
- gt  大于
- gte 大于或等于
- lt  小于
- lte 小于或等于
GET /index_test1/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "match": {
            "name": "明"
          }
        }
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 15,
            "lte": 26
          }
        }
      }
    }
  }
}
7. 精准查询(term)

term 查询是直接通过倒排索引指定的词条进行精确查找的,因为倒排索引大大缩小了检索的范围,这也使得使用term关键字的搜索效率很高。

GET /index_test1/_search
{
  "query": {
    "term": {
      "name": "明"
    }
  }
}
8. 高亮查询
GET /index_test1/_search
{
  "query": {
    "match": {
      "name": "小明"
    }
  },
  "highlight": {
    "pre_tags": "<p class='a' >",
    "post_tags": "</p>", 
    "fields": {
      "name": {}
    }
  }
}

五、在项目(JAVA)中使用ES客户端进行操作

(一)新建项目并导入项目依赖

创建一个springboot的项目 同时勾选上springboot-web的包以及Nosql的elasticsearch的包

<dependency>
     <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  </dependency>
  <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

注意,引入后要注意ElasticSearch的客户端的版本是否和本地的es版本一致


如果不一致的话,就手动配置

    <properties>
        <!-- 这里的话,要和自己本地的es版本保持一致 -->
        <elasticsearch.version>7.6.1</elasticsearch.version>
    </properties>

(二)注入RestHighLevelClient 客户端

@Configuration
public class ElasticSearchConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost",9200,"http"))
        );
        return restHighLevelClient;
    }
}

(三)使用客户端操作索引数据

1. 创建索引
    // 测试创建索引
    @Test
    void createESIndext() throws IOException {
        // 创建索引请求
        CreateIndexRequest request = new CreateIndexRequest("xiaoming_index");
        // 通过高级客户端调用相关索引客户端,并执行请求
        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        // 输出请求
        System.out.println(createIndexResponse);
    }
2. 查询索引是否存在
// 测试查询索引
    @Test
    void searchESIndext() throws IOException {
        // 创建索引请求
        GetIndexRequest request = new GetIndexRequest("xiaoming_index");
        // 通过高级客户端调用相关索引客户端,并执行请求
        boolean isExist = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        // 输出请求
        System.out.println("xiaoming_index is Exist : " + isExist);
    }
3.删除索引
 // 测试删除索引
    @Test
    void deleteESIndext() throws IOException {
        // 创建索引请求
        DeleteIndexRequest request = new DeleteIndexRequest("xiaoming_index");
        // 通过高级客户端调用相关索引客户端,并执行请求
        AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        // 输出请求
        System.out.println(response.isAcknowledged());
    }
4. 创建索引文档
// 测试创建文档
    @Test
    void createESDocument() throws IOException {
        // 创建对象
        Student stu = new Student("小明",18);
        // 创建索引相关请求
        IndexRequest request = new IndexRequest("xiaoming_index");
        // 配置请求相关参数
        request.id("1");
        request.timeout("1s");
        request.source(JSON.toJSONString(stu), XContentType.JSON);
        // 通过客户端执行请求
        IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        // 输出请求
        System.out.println(response.status());
    }
5. 判断文档是否存在
 // 判断文档是否存在
    @Test
    void searchESDocument() throws IOException {
        // 创建索引相关请求
        GetRequest request = new GetRequest("xiaoming_index", "1");
        // 配置不显示索引上下文
        request.fetchSourceContext(new FetchSourceContext(false));
        request.storedFields("_none_");
        // 获取文档信息
        boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
        // 输出请求
        System.out.println(exists);
    }
6. 获取文档内容
@Test
    void searchESDocumentDetails() throws IOException {
        // 创建索引相关请求
        GetRequest request = new GetRequest("xiaoming_index", "1");
        // 获取文档信息
        GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        // 输出具体数据
        System.out.println(response.getSourceAsString());
        // 输出全部结果
        System.out.println(response);
    }
7. 更新文档内容
 @Test
    void updateESDocumentDetails() throws IOException {
        // 创建索引相关请求
        UpdateRequest request = new UpdateRequest("xiaoming_index", "1");
        // 插入更新的文档内容
        Student student = new Student("大明", 14);
        request.doc(JSON.toJSONString(student),XContentType.JSON);
        // 更新文档信息
        UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
        // 输出具体数据
        System.out.println(response.status());
        // 输出全部结果
        System.out.println(response);
    }
8. 删除文档记录
// 删除文档记录
    @Test
    void deleteESDocumentDetails() throws IOException {
        // 创建索引相关请求
        DeleteRequest request = new DeleteRequest("xiaoming_index", "1");
        // 更新文档信息
        DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        // 输出具体数据
        System.out.println(response.status());
        // 输出全部结果
        System.out.println(response);
    }
9. 对文档记录进行批量操作
 @Test
    void bulkESDocument() throws IOException {
        // 创建批量操作索引请求
        BulkRequest bulkRequest = new BulkRequest();
        // 初始化数据
        ArrayList list = new ArrayList();
        list.add(new Student("小红", 15));
        list.add(new Student("小蓝", 15));
        list.add(new Student("小黑", 63));
        list.add(new Student("小青", 14));
        // 创建具体的插入数据请求,并加入到批量请求中
        for(int i = 0 ;i<list.size() ; i++){
            bulkRequest.add(new IndexRequest("xiaoming_index")
            .id(String.valueOf(i+1))
            .source(JSON.toJSONString(list.get(i)),XContentType.JSON));
        }
        // 执行批量操作
        BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        // 输出具体数据
        System.out.println(response.status());
        // 输出全部结果
        System.out.println(response);
    }
10.根据条件查询文档信息
 @Test
    void searchDocumentByCondition() throws IOException {
        // 创建请求对象
        SearchRequest searchRequest = new SearchRequest("xiaoming_index");
        // 创建查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("name", "蓝"));
        searchRequest.source(searchSourceBuilder);
        // 执行查询
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

参考学习视频:
【狂神说Java】ElasticSearch7.6.x最新完整教程通俗易懂
https://www.bilibili.com/video/BV17a4y1x7zq(一个蛮好的up主,大家可以多关注关注)

posted @ 2021-01-26 17:31  moutory  阅读(57)  评论(0编辑  收藏  举报  来源