ElasticSearch入门安装与SpringBoot集成实战

news2024/10/2 2:20:15

介绍

Elasticsearch 是一个实时分布式搜索和分析引擎,一般用于全文搜索、结构化搜索,分析或者三者混用。
它的底层是基于Apache Lucene(TM)的开源搜索引擎,但是lucene只是一个库,需要java开发然后集成到应用。

基础概念

在这里插入图片描述
在这里插入图片描述

应用场景

在这里插入图片描述
在这里插入图片描述

ES安装

  • centos7安装
    https://blog.csdn.net/u012069313/article/details/121660147
    https://www.likecs.com/show-308251870.html#sc=600

修改config/elasticsearch.yml
在这里插入图片描述

  • windows安装
    在这里插入图片描述

  • 启动

# 后台启动
./bin/elasticsearch -d

在这里插入图片描述

安装Head插件

https://github.com/mobz/elasticsearch-head
下载解压。

  • 安装node8+
    cd根目录,npm install

  • 解决:前端npm install 报错PhantomJS not found on PATH
    https://blog.csdn.net/qq_34254090/article/details/120313282

npm run start

在这里插入图片描述

集群配置

  • 主节点
    在这里插入图片描述
  • 新建slave1, slave2 两个es
    在这里插入图片描述

增删改查

https://www.bbsmax.com/A/kmzL44gGzG/
https://blog.csdn.net/weixin_47600880/article/details/119034733

  • 创建索引
    在这里插入图片描述
{
    "settings": {
    	"number_of_shards": 3,
    	"number_of_replicas": 1    
    },
    "mappings": {
    	"properties": {
    		"name": {
    			"type": "text"
    		},
    		"age": {
    			"type": "integer"
    		}
    	}	
    }
}

参数说明:
number_of_shards:索引分片数量
number_of_replicas:索引备份数量
mappings:索引结构化格式映射关键字
properties:设置索引的属性

  • 插入文档
    http://localhost:9200/people/_doc/1/

  • 更新文档
    http://localhost:9200/people/_update/1

  • 查询文档
    http://localhost:9200/people/_doc/1

http://localhost:9200/people/_search

{
	"query": {
		"match_all": {}
	}
}
  • 条件查询
    http://localhost:9200/people/_search
{
	"query": {
		"match": {
			"name": "治"
		}
	},
	"from": 1,
	"size": 1,
	"sort": [
		{
			"_id": {
				"order": "asc"
			}

  • 聚合查询
    http://localhost:9200/people/_search
{
	"aggs": {
		"group_by_id": {
			"terms": {
				"field": "_id"
			}
		}
	}
}

在这里插入图片描述

高级查询

Query Context
在这里插入图片描述

  • 习语查询在这里插入图片描述
  • 多字段查询
    在这里插入图片描述
  • query_string
    在这里插入图片描述
  • 范围查询
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

Springboot集成es实战

依赖:SpringBoot 2.3.7.RELEASE + ElasticSearch 8.1.1

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.test.java</groupId>
    <artifactId>springboot_es_house</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--Spring Boot Web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.44</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>8.1.1</version>
        </dependency>

        <dependency>
            <groupId>jakarta.json</groupId>
            <artifactId>jakarta.json-api</artifactId>
            <version>2.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

esclient配置类

package com.test.java.config;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author laoxu
 * @Date 2023/2/17 15:06
 * @Desc 配置ES客户端
 */
@Configuration
public class ESConfig {
    @Bean
    public ElasticsearchClient elasticsearchClient(){
        RestClient client = RestClient.builder(new HttpHost("localhost", 9200,"http")).build();
        ElasticsearchTransport transport = new RestClientTransport(client,new JacksonJsonpMapper());

        return new ElasticsearchClient(transport);
    }
}

product实体类

package com.test.java.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;

/**
 * @Author laoxu
 * @Date 2023/2/17 15:26
 * @Desc 商品实体类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Product {
    private String productName;
    private double price;
    private Integer stock;

    public String geIndexId() {
        int id = 1;
        id += id;
        String indexId = String.valueOf(id);
        return indexId;
    }
}

Junit测试类

package com.test.java;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.MatchQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.RangeQuery;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.TotalHits;
import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation;
import co.elastic.clients.elasticsearch.indices.*;
import co.elastic.clients.elasticsearch.indices.ExistsRequest;
import co.elastic.clients.json.JsonData;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import com.test.java.entity.Product;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @Author laoxu
 * @Date 2023/2/17 15:28
 * @Desc 测试ES增删改查API
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class ESApiTest {
    @Autowired
    private ElasticsearchClient esClient;

    /**
     * 判断索引是否存在
     * @throws IOException
     */
    @Test
    public void existsIndex() throws IOException {
        ExistsRequest existsRequest = new ExistsRequest.Builder().index("product").build();
        BooleanResponse existsResponse = esClient.indices().exists(existsRequest);
        System.out.println("是否存在:"+existsResponse.value());
    }
    /**
     * 创建索引
     * 创建索引时,必须是小写,否则创建报错
     * @throws IOException
     */
    @Test
    public void createIndex() throws IOException {
        CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index("product").build();
        CreateIndexResponse createIndexResponse = esClient.indices().create(createIndexRequest);
        System.out.println("是否成功:"+createIndexResponse.acknowledged());
    }

    /**
     * 删除索引
     * @throws IOException
     */
    @Test
    public void deleteIndex() throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest.Builder().index("product").build();
        DeleteIndexResponse deleteIndexResponse = esClient.indices().delete(deleteIndexRequest);
        System.out.println("是否成功:"+deleteIndexResponse.acknowledged());
    }

    /**
     * 同步方式
     * 向索引中添加信息,此操作不存在索引时会直接创建索引,使用时需要各种校验使逻辑更严谨
     * @throws IOException
     */
    @Test
    public void setIndex() throws IOException {
        Product product = new Product("帽子",44.5,9);
        IndexRequest<Product> indexRequest = new IndexRequest.Builder<Product>().index("product")
                .id(String.valueOf(product.getStock()))
                .document(product)
                .build();
        IndexResponse indexResponse = esClient.index(indexRequest);
        System.out.println(indexResponse);
    }

    /**
     * 批量写入数据
     * @throws IOException
     */
    @Test
    public void bulkIndex() throws IOException{
        List<Product> products = new ArrayList<Product>();
        products.add(new Product("香烟",135,1));
        products.add(new Product("瓜子",154,2));
        products.add(new Product("矿泉水",613,3));
        products.add(new Product("酱油",72,4));
        products.add(new Product("大米",771,5));
        BulkRequest.Builder bk = new BulkRequest.Builder();
        int indexId = 4;
        for (Product product:products) {
            bk.operations(op->op.index(i->i.index("product")
                    .id(UUID.randomUUID().toString())
                    .document(product)));
        }
        BulkResponse response = esClient.bulk(bk.build());
        if (response.errors()) {
            System.out.println("Bulk had errors");
            for (BulkResponseItem item: response.items()) {
                if (item.error() != null) {
                    System.out.println(item.error().reason());
                }
            }
        }
    }

    /**
     * 根据索引文档id获取文档信息
     * @throws IOException
     */
    @Test
    public void getIndexById() throws IOException {
        GetRequest getRequest = new GetRequest.Builder().index("product")
                .id("9")
                .build();
        GetResponse<Product> response = esClient.get(getRequest, Product.class);
        if (response.found()) {
            Product product = response.source();
            System.out.println("Product name " + product.getProductName());
            System.out.println("Product price " + product.getPrice());
        } else {
            System.out.println("Product not found");
        }
    }

    /**
     * 简单查询文档信息
     * @throws IOException
     */
    @Test
    public void getSearch() throws IOException{
        /*此处 .from(1).size(2) 表示分页查询,从第一页开始查询,大小为两条*/
        SearchRequest searchRequest = new SearchRequest.Builder().index("product")
                .query(q -> q.match(m -> m.field("productName").query("烟"))).from(1).size(2).build();

        SearchResponse<Product> response = esClient.search(searchRequest,Product.class);

        TotalHits total = response.hits().total();
        boolean isExactResult = total.relation() == TotalHitsRelation.Eq;

        if (isExactResult) {
            System.out.println("There are " + total.value() + " results");
        } else {
            System.out.println("There are more than " + total.value() + " results");
        }

        List<Hit<Product>> hits = response.hits().hits();
        for (Hit<Product> hit: hits) {
            Product product = hit.source();
            System.out.println("Found product " + product.getProductName() + ", score " + hit.score());
        }
    }

    /**
     * 多条件嵌套查询文档信息
     * @throws IOException
     */
    @Test
    public void getSearchs() throws IOException{
        String productName = "衣服";
        double price = 115;

        //按照产品名称搜索
        Query byname = MatchQuery.of(m -> m.field("productName")
                .query(productName))._toQuery();

        //按照产品价格搜索
        Query byprice = RangeQuery.of(r -> r
                .field("price")
                .gte(JsonData.of(price))
        )._toQuery();

        //结合名称和价格查询
        SearchResponse<Product> response = esClient.search(s -> s
                        .index("product")
                        .query(q -> q
                                .bool(b -> b
                                        .must(byname)
                                        .must(byprice)
                                )
                        )
                        .from(1)
                        .size(2),
                Product.class
        );

        List<Hit<Product>> hits = response.hits().hits();
        for (Hit<Product> hit : hits){
            Product product = hit.source();
            System.out.println(product.getProductName()+" "+product.getPrice());
        }
    }

}

效果展示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/352460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode刷题复盘笔记—一文搞懂贪心算法之452. 用最少数量的箭引爆气球(贪心算法系列第十一篇)

今日主要总结一下可以使用贪心算法解决的一道题目&#xff0c;452. 用最少数量的箭引爆气球 题目&#xff1a;452. 用最少数量的箭引爆气球 Leetcode题目地址 题目描述&#xff1a; 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#…

备战蓝桥杯【二维前缀和】

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

【自学MYSQL】MySQL Windows安装

MySQL Windows安装 MySQL Windows下载 首先&#xff0c;我们打开 MySQL 的官网&#xff0c;网址如下&#xff1a; https://dev.mysql.com/downloads/mysql/在官网的主页&#xff0c;我们首先根据我们的操作系统&#xff0c;选择对应的系统&#xff0c;这里我们选择 Windows&…

神奇的nextTick一定能获取到最新的dom么?

前言 众所周知&#xff0c;vue的dom更新操作时异步的&#xff0c;为了获取更新后的dom官方提供了相应的apinextTick,文档中对该api的描述为&#xff1a;将回调延迟到下次 DOM 更新循环之后执行 , 所谓的下一次&#xff0c;到底是哪一次呢&#xff1f;dom更新是异步任务&#xf…

【数据结构与算法】链表1:移除链表 设计链表链表反转(双指针法、递归法)

文章目录今日任务1.链表理论基础&#xff08;1&#xff09;什么是链表&#xff1f;&#xff08;2&#xff09;链表的类型&#xff08;3&#xff09;链表的存储方式&#xff08;4&#xff09;链表的定义&#xff08;5&#xff09;链表的操作&#xff08;6&#xff09;性能分析2.…

【设计模式】综述

设计模式概述 文章目录一、设计模式1. 基本简介2. 面向对象设计原则二、基本类别1. 创建型模式会更新每种模式的详细博客超链接&#xff0c;敬请期待呀参考博客&#x1f60a;点此到文末惊喜↩︎ 一、设计模式 1. 基本简介 定义&#xff1a;设计模式是一个针对重复发生的问题的…

使用HTTP隧道代理,请求超过频率要怎么办?

在网上&#xff0c;经常会看到有人说使用隧道代理经常遇到429错误&#xff08;请求超过频率&#xff09;&#xff0c;我们要如何解决这一问题呢&#xff1f;通常情况&#xff0c;优质的HTTP代理厂商隧道代理服务器采用的是高性能主机构建的动态IP代理服务器&#xff0c;是可以支…

IO流

标题IO流的体系结构FileReader和FileWriterFileReader读入数据的基本操作FileReader中使用read(char [] cbuf)读入数据FileWriter写出数据字节流使用FileInputStream和FileOutputStream读写文本文件使用FileInputStream和FileOutputStream读写非文本文件缓冲流缓冲流&#xff0…

智慧校园平台源码:实现互联互通的校园管理一体化

智慧校园管理平台主要以校园安全、智慧校园数据管理云平台为核心&#xff0c;实现数据统一管理&#xff0c;以智慧电子班牌为学生智慧之窗&#xff0c;以移动管理平台、家校沟通为辅。实现教师—家长一学校—学生循环的无纸化管理模式及教学服务&#xff0c;实现多领域的信息互…

【JavaSE】Lambda、Stream(659~686)

659.每天一考 1.写出获取Class实例的三种常见方式 Class clazz1 String.class; Class clazz2 person.getClass(); //sout(person); //xxx.yyy.zzz.Person... Class clazz3 Class.forName(String classPath);//体现反射的动态性2.谈谈你对Class类的理解 Class实例对应着加载…

小小bat-day1-自动文件上传

前言&#xff1a;日常服务器备份文件或者生产设备等数据文件都统一保存至文件服务器&#xff0c;进行日志分析或者将生产文件CSV、图片等转存至数仓进行数据分析&#xff0c;尤其生产的部分数据是保存在个人电脑的PC端&#xff0c;数据杂&#xff0c;获取困难&#xff0c;手动整…

day45【代码随想录】动态规划之完全平方数、单词拆分、打家劫舍、打家劫舍 II

文章目录前言一、完全平方数&#xff08;力扣279&#xff09;二、单词拆分&#xff08;力扣139&#xff09;三、打家劫舍&#xff08;力扣198&#xff09;四、打家劫舍 II前言 1、完全平方数 2、单词拆分 3、打家劫舍 4、打家劫舍 II 一、完全平方数&#xff08;力扣279&#…

2023软考报名(上半年)报名什么时候开始?-弘博创新

2023软考报名&#xff08;上半年&#xff09;报名预计在3月底-4月初开始&#xff0c;现在可以先进入备考了&#xff0c;参加学习可以到弘博创新&#xff0c;专业考前辅导多年&#xff0c;专业靠谱&#xff01; 系统集成项目管理工程师是全国计算机技术与软件专业技术资格&#…

Windows安装VMware虚拟机+配置Ubuntu的详细步骤以及解决配置过程中报错的问题(完整版)

目录 引言: 过程&#xff1a; 安装VMware虚拟机&#xff1a; 在VMware虚拟机中配置Ubuntu&#xff1a; 在VMware虚拟机中安装Ubuntu&#xff1a; VMware中启动虚拟机时报错问题的解决&#xff1a; 正式开始安装Ubuntu&#xff1a; 参考资料&#xff1a; 引言: 在学习计…

线程池源码解析项目中如何配置线程池

目录 基础回顾 线程池执行任务流程 简单使用 构造函数 execute方法 execute中出现的ctl属性 execute中出现的addWorker方法 addWorker中出现的addWorkerFailed方法 addWorker中出现的Worker类 Worker类中run方法出现的runWorker方法 runWorker中出现的getTask runWo…

Websocket详细介绍

需求背景 在某个资产平台&#xff0c;在不了解需求的情况下&#xff0c;我突然接到了一个任务&#xff0c;让我做某个页面窗口的即时通讯&#xff0c;想到了用websocket技术&#xff0c;我从来没用过&#xff0c;被迫接受了这个任务&#xff0c;我带着浓烈的兴趣&#xff0c;就…

MinIO

概述MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是任意大小&#xff0c;从…

Redis学习【7】之发布_订阅命令和事务

文章目录一 发布/订阅命令1.1 消息系统1.2 subscribe1.3 psubscribe1.4 publish1.5 unsubscribe1.6 punsubscribe1.7 pubsub1.7.1 pubsub channels1.7.2 pubsub numsub1.7.3 pubsub numpat二 Redis 事务2.1 Redis 事务特性Redis 事务实现2.1.1 三个命令2.1.2 基本使用2.2. Redi…

家用洗地机哪款质量好?洗地机排行榜

伴随着人们消费水平和生活品质的提升&#xff0c;人们对家庭中的需求也随之提高&#xff0c;洗地机凭借着吸拖洗为一体的功能深受大众喜爱&#xff0c;但是市面上洗地机产品越来越多&#xff0c;清洁效果也参差不齐&#xff0c;到底哪款洗地机质量好呢&#xff0c;跟随笔者脚步…

FILE文件操作

文件指针 每个被使用的文件都在内存中开辟了一个相应的文件信息区&#xff0c;用来存放文件的相关信息&#xff08;如文件的名 字&#xff0c;文件状态及文件当前的位置等&#xff09;。这些信息是保存在一个结构体变量中的。该结构体类型是有系统 声明的&#xff0c;取名FILE…