ElasticSearch的学习概述

简介

​ 以下内容摘自百度百科

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。ElasticSearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎

Lucene是大神Dong cutting开发的提供全文信息检索引擎的工具jar包,底层用java代码书写, 但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎

Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆

​ 以下内容ElasticSearch均简称为es

Kibana介绍

ELK中的K,Kibana

下面就Kibana对ES的查询监控作介绍,就是常提到的大数据日志处理组件ELK里的K。

什么是Kibana?

Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana,可以通过各种图表进行高级数据分析及展示。

Kibana让海量数据更容易理解。它操作简单,基于浏览器的用户界面可以快速创建仪表板(dashboard)实时显示Elasticsearch查询动态。

设置Kibana非常简单。无需编码或者额外的基础架构,几分钟内就可以完成Kibana安装并启动Elasticsearch索引监测。

ES的安装及使用

安装

前提

  • es的jdk版本必须大于1.8
  • 下载es的客户端和界面工具head插件
  • 下载es的监控工具Kibana==【版本需要和es一致】==

es的安装地址

国内安装国外软件速度过慢,而且es的体积有好几百兆,为了加快速度,推荐国内镜像网站下载

在这里插入图片描述

Kibana的安装

国内镜像网站

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-24w9d0Ey-1643947892235)(C:\Users\86155\AppData\Roaming\Typora\typora-user-images\1642732065177.png)]

ik分词器

github下载地址

在这里插入图片描述

elasticsearch-head-master可视化界面

点击即可下载

使用

1、下载好的ElasticSearch解压即可使用
2、es默认访问端口号为9200

3、config文件夹加载了当前es的配置,其中config/jvm.options的默认占用内存为1g,也就是说,只要一启动es服务器,你的电脑就会被占用1g内存,所以电脑不好的小伙伴,可千万不要尝试哦

在这里插入图片描述

4、plugins文件夹下加载了插件

启动ES服务器

进入bin目录,双击elasticsearch.bat即可

启动成功后,在浏览器输入localhost:9200即可访问

访问成功后页面

在这里插入图片描述

ES可视化插件head的使用

解压完毕后进入es head界面,在文件输入栏中打开cmd,输入cnpm install命令

注意:必须要有node环境

安装完毕后输入npm run start命令即可启动前端页面

在这里插入图片描述

可见启动端口号为localhost:9100,但是由于跨域问题,这个前端页面还未和es服务器建立连接

ES解决和head前端连接的跨域问题

第一步,打开es文件目录下config/elasticsearch.yml文件

第二步,输入下面两行代码==【注意:是yml格式,yml冒号后须有空格】==

http.cors.enabled: true  	#表示开启跨域支持
http.cors.allow-origin: "*" #表示允许所有人访问

第三步,重启ES

成功启动后页面

在这里插入图片描述

​ head中共有5个标签栏,每个标签栏代表了不同的功能,其中第三个数据浏览的标签,会展示所有es存储的数据,我们只会用这个,其他的功能我们不用,基本查询复合查询功能,我们会用kibana来进行

【注】其实任何可以发送请求的工具都可以用来操作ES,ES本质上就是一个java开发的服务器,用户可以通过发送不同的REST风格的请求来操作服务器,所以这里用postMan也是一样的

Kibana使用

kibana本质上也是一个前端工程,解压后即可使用。

由于其默认为英文界面,我们可以通过修改配置修改成中文界面。

打开Kibana之前要先打开ES

在这里插入图片描述

汉化方式:

​ 查看根目录下/x-pack/plugins/translations/translations/zh-CN.json

如果存在这个json文件就能进行汉化

然后打开根目录下/config/kibana.yml文件

1、服务的端口配置:
属性名为:server.port默认是5601
2、允许远程访问的地址配置:
属性名为:server.host默认为本机,如果我们需要把Kibana服务给远程主机访问,只需要在这个配置中填写远程的那台主机的ip地址,那如果我们希望所有的远程主机都能访问,那就填写0.0.0.0
3、连接Elasticsearch服务配置
属性名为:elasticsearch.url默认为连接到本机的elasticsearch,并且端口为9200,也就是localhost:9200,如果我们Elasticsearch不是与Kibana安装在同一台主机上,或者Elasticsearch的端口号不是9200,就就需要修改这个配置了
4、Elasticsearch的用户名和密码
属性名为:elasticsearch.username和elasticsearch.password,默认是没有用户名和密码,如elasticsearch是配置了用户名和密码的,那就需要配置这两行属性

在最后一行加上一句代码

i18n.locale: "zh-CN"

第一次启动过于缓慢,请耐心等待

ES基本实例

  1. 你经营一个网上商店,你允许你的顾客搜索你卖的产品。在这种情况下,您可以使用Elasticsearch来存储整个产品目录和库存,并为它们提供搜索和自动完成建议。
  2. 你希望收集日志或事务数据,并希望分析和挖掘这些数据,以查找趋势、统计、汇总或异常。在这种情况下,你可以使用loghide (Elasticsearch/ loghide /Kibana堆栈的一部分)来收集、聚合和解析数据,然后让loghide将这些数据输入到Elasticsearch中。一旦数据在Elasticsearch中,你就可以运行搜索和聚合来挖掘你感兴趣的任何信息。
  3. 你运行一个价格警报平台,允许精通价格的客户指定如下规则:“我有兴趣购买特定的电子设备,如果下个月任何供应商的产品价格低于X美元,我希望得到通知”。在这种情况下,你可以抓取供应商的价格,将它们推入到Elasticsearch中,并使用其反向搜索(Percolator)功能来匹配价格走势与客户查询,并最终在找到匹配后将警报推送给客户。
  4. 你有分析/业务智能需求,并希望快速调查、分析、可视化,并对大量数据提出特别问题(想想数百万或数十亿的记录)。在这种情况下,你可以使用Elasticsearch来存储数据,然后使用Kibana (Elasticsearch/ loghide /Kibana堆栈的一部分)来构建自定义仪表板,以可视化对您来说很重要的数据的各个方面。此外,还可以使用Elasticsearch聚合功能对数据执行复杂的业务智能查询。

ES基本概念

Cluster(集群)

ES自打开就只有集群的概念,就算只打开了一个,它也是一个集群,这是为了满足分布式的需要,在大数据的生态下,集群符合了现代互联网的发展趋势。你可以随意扩展ES服务器,然后将他们构成一个集群。

集群是一个或多个节点(服务器)的集合,它们共同保存你的整个数据,并提供跨所有节点的联合索引和搜索功能。==一个集群由一个唯一的名称标识,默认这个唯一标识的名称是"elasticsearch"。==这个名称很重要,因为如果节点被设置为按其名称加入集群,那么节点只能是集群的一部分。

确保不要在不同的环境中用相同的集群名称,否则可能导致节点加入到错误的集群中。例如,你可以使用"logging-dev", “logging-test”, "logging-prod"分别用于开发、测试和正式集群的名字。

Index(索引)

索引是具有某种相似特征的文档的集合。例如,你可以有一个顾客数据索引,产品目录索引和订单数据索引。索引有一个名称(必须是小写的)标识,该名称用于在对其中的文档执行索引、搜索、更新和删除操作时引用索引。

如果对比Mysql,那么索引就相当于Mysql的一张数据表

Node(节点)

节点是一个单独的服务器,它是集群的一部分,存储数据,并参与集群的索引和搜索功能。就像集群一样,节点由一个名称来标识,默认情况下,该名称是在启动时分配给节点的随机通用唯一标识符(UUID)。如果不想用默认的节点名,可以定义任何想要的节点名。这个名称对于管理来说很重要,因为你希望识别网络中的哪些服务器对应于你的Elasticsearch集群中的哪些节点。

一个节点可以通过配置集群名称来加入到一个特定的集群中。默认情况下,每个节点都被设置加入到一个名字叫"elasticsearch"的集群中,这就意味着如果你启动了很多个节点,并且假设它们彼此可以互相发现,那么它们将自动形成并加入到一个名为"elasticsearch"的集群中。

一个集群可以有任意数量的节点。此外,如果在你的网络上当前没有运行任何节点,那么此时启动一个节点将默认形成一个单节点的名字叫"elasticsearch"的集群,对比Mysql的话,一个节点便相当于一个数据库。

Document(文档)

文档是可以被索引的基本信息单元。文档用JSON表示。

Index里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。Document 使用 JSON 格式表示。同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。

对比Mysql,文档相当于Mysql中的每一行数据,只不过数据是用JSON格式存储和读取的

Shards & Replicas(复制品,分片)

一个索引可能存储大量数据,这些数据可以超过单个节点的硬件限制。例如,一个包含10亿条文档占用1TB磁盘空间的索引可能不适合在单个节点上,或者可能太慢而不能单独处理来自单个节点的搜索请求。

为了解决这个问题,Elasticsearch提供了将你的索引细分为多个碎片(或者叫分片)的能力。在创建索引时,可以简单地定义所需的分片数量。每个分片本身就是一个功能完全独立的“索引”,可以驻留在集群中的任何节点上。

分片之所以重要,主要有两个原因:

  • 它允许你水平地分割/扩展内容卷
  • 它允许你跨分片(可能在多个节点上)分布和并行操作,从而提高性能和吞吐量

在一个网络/云环境中随时都有可能出现故障,强烈推荐你有一个容灾机制。Elasticsearch允许你将一个或者多个索引分片复制到其它地方,这被称之为副本

复制之所以重要,有两个主要原因:

  • 它提供了在一个shard/node失败是的高可用性。出于这个原因,很重要的一个点是一个副本从来不会被分配到与它复制的原始分片相同节点上。也就是说,副本是放到另外的节点上的。
  • 它允许扩展搜索量/吞吐量,因为搜索可以在所有副本上并行执行。

总而言之,每个索引都可以分割成多个分片。索引也可以不被复制或复制多次。一旦被复制,每个索引都将具有主分片(被复制的原始分片)和副本分片(主分片的副本)。在创建索引时,可以为每个索引定义分片和副本的数量。创建索引后,您可以随时动态地更改副本的数量,但不能更改事后分片的数量。

在默认情况下,Elasticsearch中的每个索引都分配了5个主分片和1个副本,这意味着如果集群中至少有两个节点,那么索引将有5个主分片和另外5个副分片(PS:这5个副分片组成1个完整副本),每个索引总共有10个分片(5个原有的,5个复制的)。

倒排索引(Inverted Index)

该索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。Elasticsearch能够实现快速、高效的搜索功能,正是基于倒排索引原理。

类型(Type)

Document 可以分组,比如employee这个 Index 里面,可以按部门分组,也可以按职级分组。这种分组就叫做 Type,它是虚拟的逻辑分组,用来过滤 Document,类似关系型数据库中的数据表。
 不同的 Type 应该有相似的结构(Schema),性质完全不同的数据(比如 products 和 logs)应该存成两个 Index,而不是一个 Index 里面的两个 Type(虽然可以做到)。

注意:在ES 7.x的版本中,已经弱化了Type的概念,变得可有可无了

文档元数据(Document metadata)

文档元数据为_index, _type, _id, 这三者可以唯一表示一个文档,_index表示文档在哪存放,_type表示文档的对象类别,_id为文档的唯一标识。

字段(Fields)

每个Document都类似一个JSON结构,它包含了许多字段,每个字段都有其对应的值,多个字段组成了一个 Document,可以类比关系型数据库数据表中的字段。
 在 Elasticsearch 中,文档(Document)归属于一种类型(Type),而这些类型存在于索引(Index)中,下图展示了Elasticsearch与传统关系型数据库的类比:
在这里插入图片描述

IK分词器

思考一个问题?为什么在百度上搜索时,输入一个词语,百度能够判别这是否是一个词还是一个字呢?

IK只使用于中文

这是用算法实现的,在中文中,有些汉字可以组成词语,有些汉字不能,英文也是如此。所以在IK分词插件中存在很多字典文件。这些字典文件中存储了大量常用的词语,当输入某一段话时,ES会使用IK插件的算法进行分词,然后分别拿这些词去指定的索引中匹配搜索。

IK提供了两个分词算法

  • 一个是ik_smart,最少切分
  • 一个是ik_max_word,最细粒度划分

安装好IK分词器后,下面拿Kibana进行测试


在Kibana中的请求格式与PostMan不同,下面可以看看这两种请求格式的不同之处

PostMan

http://localhost:9200/_search?query=match_all ——get方式

Kibana

GET _search
{
  "query": {
    "match_all": {}
  }
}

其中在Kibana中,默认的访问地址就是localhost:9200,_search代表了请求地址,括号内的数据代表了请求体。

IK两种算法的区别

ik_smart

GET _analyze
{
  "analyzer": "ik_smart",
  "text": "我爱China,天空中的云彩"
}

结果

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "爱",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "china",
      "start_offset" : 2,
      "end_offset" : 7,
      "type" : "ENGLISH",
      "position" : 2
    },
    {
      "token" : "天空中",
      "start_offset" : 8,
      "end_offset" : 11,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "的",
      "start_offset" : 11,
      "end_offset" : 12,
      "type" : "CN_CHAR",
      "position" : 4
    },
    {
      "token" : "云彩",
      "start_offset" : 12,
      "end_offset" : 14,
      "type" : "CN_WORD",
      "position" : 5
    }
  ]
}

ik_max_word

GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "我爱China,天空中的云彩"
}

结果

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "爱",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "china",
      "start_offset" : 2,
      "end_offset" : 7,
      "type" : "ENGLISH",
      "position" : 2
    },
    {
      "token" : "天空中",
      "start_offset" : 8,
      "end_offset" : 11,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "天空",
      "start_offset" : 8,
      "end_offset" : 10,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "空中",
      "start_offset" : 9,
      "end_offset" : 11,
      "type" : "CN_WORD",
      "position" : 5
    },
    {
      "token" : "的",
      "start_offset" : 11,
      "end_offset" : 12,
      "type" : "CN_CHAR",
      "position" : 6
    },
    {
      "token" : "云彩",
      "start_offset" : 12,
      "end_offset" : 14,
      "type" : "CN_WORD",
      "position" : 7
    }
  ]
}

通常情况下,ik_max_word会将所有能组合的词全部组合起来,而ik_smart只会挑最优组合,分词数量也比ik_max_word少

自己造词

有些词会被分开,这是我们不想看到的结果,所以我们可以自定义字典然后造词

打开ik根目录下/config/IKAnalyzer.cfg.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict"></entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- <entry key="remote_ext_dict">words_location</entry> -->
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

然后在同级目录下创建dic文件,在文件中输入自己不想被拆解的词即可

ES基本REST操作

基本Rest命令说明

methodurl地址描述
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/索引名称/类型名称/文档id/_search查询所有数据

在7.x的 版本中,类型名称已经不用加了,再加了类型后会报错

ES中的数据类型

  • 字符串类型
    • text、keyword
      • text:支持分词,全文检索,支持模糊、精确查询,不支持聚合,排序操作;text类型的最大支持的字符长度无限制,适合大字段存储;
      • keyword:不进行分词,直接索引、支持模糊、精确匹配,支持聚合、排序操作。keyword类型的最大支持的长度为——32766个UTF-8类型的字符,可以通过设置ignore_above指定自持字符长度,超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果。
  • 数值型
    • long、Integer、short、byte、double、float、half floatscaled float
  • 日期类型
    • date
  • te布尔类型
    • boolean
  • 二进制类型
    • binary
  • 等等…

解释

ES中的所有操作均是请求的方式来修改ES数据库的内容,所有语法也是基于REST风格的,只需要根据语法发送不同的请求,就能执行不同的功能并从es数据库中获取到不同的信息,这一点,和操作Mysql的语法是一样的。所以要想学好es,es的基本操作语法必须熟练掌握,这里就不再赘述语法,接下来将直接和Springboot代码集成。

Springboot集成ES操作ES数据库

修改es版本

查看springboot 依赖源码

在这里插入图片描述

会发现默认的es版本号为7.15.2,我们要保证版本号的一致,所以手动修改es的版本,在pom.xml文件中修改properties属性

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.6.2</elasticsearch.version>
    </properties>

注册es客户端

新建一个config包,书写下面代码

package com.es.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author whr
 * @description es配置类
 */
@Configuration
public class MyElasticSearchConfig {

    @Bean
    public RestHighLevelClient esClient(){
//        注册高版本客户端,第一步先获取到es客户端
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
                new HttpHost("localhost", 9200, "http")
        ));
        return client;
    }
}

关于索引的操作

通过客户端的indices下的方法,可以执行和索引本身结构有关的方法

测试创建索引代码

package com.es;

import lombok.SneakyThrows;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class HrApplicationTests {

    /**
     * client代表了es客户端,可以用client对象代替es客户端进行各种操作
     */
    @Autowired
    @Qualifier("esClient")
    private RestHighLevelClient client;

    /**
     * 创建索引【理解成创建数据库】
     */
    @SneakyThrows //lombok注解,用来偷偷的处理异常
    @Test
    public void testCreateIndex(){
        //创建一个“创建索引”的请求对象来发出请求,参数为index,及要创造的索引名,
        // 相当于语法PUT 索引名
        CreateIndexRequest req = new CreateIndexRequest("java_create_index");
        //indices是index的复数形式,代表了所有关于索引本身结构的方法
        CreateIndexResponse resp = client.indices().create(req, RequestOptions.DEFAULT);
        //输出响应的各项指标查看
        System.out.println(resp.index());//输出创建的索引名 java_create_index
        System.out.println(resp.isAcknowledged());//输出是否创建成功 true
        System.out.println(resp.isFragment());//输出是否是分片 false
        //一定不要忘记关闭连接以节省资源
        client.close();
    }

}

测试索引是否存在

/**
     * 测试某个索引是否存在
     */
    @SneakyThrows
    @Test
    public void testGetIndex(){
//        第一参数为获取索引请求对象,第二个参数为这个请求做一些设置
        boolean isExist = client.indices().exists(
                new GetIndexRequest("java_create_index"), RequestOptions.DEFAULT);
        System.out.println(isExist); //true
        client.close();
    }

删除某个索引

/**
     * 删除索引,注意,只有管理员能删除索引
     */
    @SneakyThrows
    @Test
    public void testDelIndex(){
//        这里的参数可以为多个,也可以为1个,也可以没有,指定要删除的索引
        DeleteIndexRequest req = new DeleteIndexRequest("java_create_index");
//        客户端发送删除请求
        AcknowledgedResponse resp = client.indices().delete(req, RequestOptions.DEFAULT);
        System.out.println(resp.isAcknowledged());//true
        client.close();
    }

文档的操作

操作文档的方法在client对象下

添加文档

   /**
     * 测试添加文档
     */
    @Test
    @SneakyThrows
    public void testAddDocument(){
//        创建user对象,插入es的数据
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        user.setSex("男");
//        创建插入文档的请求,参数指定要插入的索引名
        IndexRequest indexRequest = new IndexRequest("java_create_index");
//        指定要插入文档的id,如果不指认,将默认按照UUID的方式随机生成一个id
        indexRequest.id("1");
//        指定插入超时时间,一旦超时便报错
        indexRequest.timeout("1s");
//        指定要插入的数据,要转换成json字符串的格式,第二个参数用来指明发送数据的请求格式,
//        相当于header中的ContentType
        indexRequest.source(JSON.toJSONString(user), XContentType.JSON);
//        客户端发送添加文档的请求,利用index方法,返回响应
        IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
//        查看返回响应的信息
        System.out.println(response); 
//        查看插入索引的建立状态
        System.out.println(response.status());//CREATED
        client.close();
    }

获取单个文档信息

/**
     * 单个文档信息的获取
     */
    @Test
    @SneakyThrows
    public void testGetIndexDocument(){
//        可以无参数,会产生一些默认配置
//        获取java_create_index中id为1的文档
        GetRequest request = new GetRequest("java_create_index","1");
//        通过fetchSourceContext(new FetchSourceContext(false));可以不获取_source下的内容
//        通过fetchSourceContext还可以获取指定的字段信息,这里忽略了sex字段
        request.fetchSourceContext(new FetchSourceContext(true,new String[]{"name","age"},new String[]{}));
//      判断文档是否存在
        boolean exists = client.exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);//true
//        如果存在则输出文档信息
        if(exists){
            GetResponse documentFields = client.get(request, RequestOptions.DEFAULT);
            System.out.println(documentFields);
            System.out.println(documentFields.getSourceAsString());
        }

    }

结果

true
{"_index":"java_create_index","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"name":"张三","age":18}}
{"name":"张三","age":18}

更新文档

// 测试更新文档内容
@Test
public void testUpdateDocument() throws IOException {
    UpdateRequest request = new UpdateRequest("java_create_index", "1");
    User user = new User("lmk",11);
    //指定修改数据
    request.doc(JSON.toJSONString(user),XContentType.JSON);
    UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
    System.out.println(response.status()); // OK
    client.close();
}

删除文档

// 测试删除文档
@Test
public void testDeleteDocument() throws IOException {
    DeleteRequest request = new DeleteRequest("java_create_index", "1");
    request.timeout("1s");
    DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
    System.out.println(response.status());// OK
    client.close();
}

查询文档

  /**
     * 建立搜索条件并将搜索内容高亮
     */
    @Test
    @SneakyThrows
    public void testSearchIndexDocument(){
//        创建查询对象,如果为空默认查询所有索引
        SearchRequest request = new SearchRequest("java_create_index");
//        创建搜索条件,这个对象是创建复杂的搜索条件的基础
        SearchSourceBuilder builder = new SearchSourceBuilder();
//        创建查询条件,通过QueryBuilders工具类创建
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name","张");
//         将查询条件装载进builder对象
        builder.query(matchQueryBuilder);
//         将高亮条件装载进builder对象
        builder.highlighter(new HighlightBuilder().field("name").preTags("<p style='color:red'>").postTags("</p>"));
//         将所有条件注入请求中
        request.source(builder);
//        发送请求
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        System.out.println(JSON.toJSONString(searchHits));
        System.out.println("=======================");
        for (SearchHit hit : searchHits.getHits()) {
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            System.out.println(sourceAsMap);
            Text[] fragments = name.getFragments();
            String content="";
            for (Text fragment : fragments) {
                content+=fragment;
            }
            System.out.println(content);
            sourceAsMap.put("name",content);
            System.out.println(sourceAsMap);
        }
    }

批量插入数据

// 特殊的,真的项目一般会 批量插入数据
@Test
public void testBulk() throws IOException {
    //bulk的意思是大量的
    BulkRequest bulkRequest = new BulkRequest();
    bulkRequest.timeout("10s");
    ArrayList<User> users = new ArrayList<>();
    users.add(new User("liuyou-1",1));
    users.add(new User("liuyou-2",2));
    users.add(new User("liuyou-3",3));
    users.add(new User("liuyou-4",4));
    users.add(new User("liuyou-5",5));
    users.add(new User("liuyou-6",6));
    // 批量请求处理
    for (int i = 0; i < users.size(); i++) {
        bulkRequest.add(
                // 这里是数据信息
                new IndexRequest("bulk")
                        .id(""+(i + 1)) // 没有设置id 会自定生成一个随机id
                        .source(JSON.toJSONString(users.get(i)),XContentType.JSON)
        );
    }
    BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
    System.out.println(bulk.status());// ok
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值