Elasticsearch

发布于:2025-06-18 ⋅ 阅读:(19) ⋅ 点赞:(0)

目录

Elasticsearch介绍

Elasticsearch安装及Kibana的使用

Elasticsearch服务安装       

Kibana安装 

分词器

默认分词器

IK分词器

Kibana操作

索引操作

文档操作

文档数据搜索

Springboot集成Elasticsearch

集成版本说明

添加elasticsearch 依赖

项目配置elasticsearch

编写测试代码测试


Elasticsearch介绍

        Elasticsearch 是一个开源的分布式搜索和分析引擎,专为速度、扩展和 AI 应用而打造。作为一个检索平台,它可以实时存储结构化、非结构化和向量数据,提供快速的混合和向量搜索,支持可观测性与安全分析,并以高性能、高准确性和高相关性实现 AI 驱动的应用。

        Elasticsearch 主要适用实时快速的全文搜索场景,它是分布式的,基于Restful分隔的API操作索引文档等,它和数据库(如Mysql)类比如下:

        Elasticsearch核心的概念:分词、倒排索引、TD/IDF打分、分布式集群 。

        分词:Elasticsearch默认分词器,根据空格和标点符号对英文进行分词,会进行单词的大小写转换,对中文搜索效果很差,IK分词器可以实现中文搜索效果。

        倒排索引,也可以理解为反向索引,传统数据库的正向索引都是按照表的id正向的找到行的记录;Elasticsearch倒排索引是指通过文档关键词(分词后)指向对应的数据库的id,进而找到真正的数据库行记录,示意图如下(左图是正向索引、右图是倒排索引):

        TD/IDF打分:用于对查询结果的排序。TD-IDF是一种统计方法,用于评估一个词在文档集中的重要程度。它的值越大,表示这个词在整个语料库中就越重要。TD-IDF算法由两部分组成:词频 (TF) 和逆文档频率 (IDF)。

        分布式集群:Elasticsearch基于Raft协议选举leader。下图示例中,假定集群中有5个节点,节点3是leader,其他节点是从节点。索引数据分3片存储,每片数据有1份备份。

        从上面的示意图可以看出,当客户端写入索引数据时,请求到集群任意一个节点,节点会自动转发给要写入的节点(假定索引数据要写入到分片1) ,写入完成后,并将分片1的数据同步到节点4。

        

         从上面的示意图可以看出,当客户端查询数据时,请求到集群任意一个节点,假设请求的节点只包含分片1的数据,此时当前节点会分别转发包含分片2和分片3数据的节点,最终会汇总分片1-2-3的数据后返回给客户端。

Elasticsearch安装及Kibana的使用

Elasticsearch服务安装       

        安装步骤如下:

        1、下载地址:Download Elasticsearch | Elastic (本文演示Windows平台),版本:8.17.3,下载elasticsearch-8.17.3-windows-x86_64.zip

        2、解压elasticsearch-8.17.3-windows-x86_64.zip,运行elasticsearch.bat 启动

        3、浏览器输入https://localhost:9200/ ,输入用户名密码elastic、NKzxfY05pHVHBwEh1na0 登录验证(用户名密码可以通过bin/elasticsearch-reset-password.bat 重置密码)

Kibana安装 

        Kibana是一款开源的数据分析和可视化平台,用于和Elasticsearch协作。可以使用Kibana对Elasticsearch索引中的数据进行搜索、查看、交互操作。安装步骤如下:

        1、下载和Elasticsearch相同版本的kibana,下载地址:Download Kibana Free | Get Started Now | Elastic ,下载版本:kibana-8.17.3-windows-x86_64.zip

        2、解压kibana-8.17.3-windows-x86_64.zip,修改config/kibana.yml 添加中文支持

        3、运行bin/kibana.bat 启动,浏览器输入:http://localhost:5601/ ,输入和Elasticsearch 服务相同的用户名密码登录

分词器

        ES文档的数据拆分成一个个有完整含义的关键词,并将关键词与文档对应,这样就可以通过关键词查询文档。要想正确的分词,需要选择合适的分词器。本文主要介绍默认分词器和IK分词器。

默认分词器

        standard analyzer,默认分词器,根据空格和标点符号对英文进行分词,会进行单词的大小写转换。通过Kibana控制台查看此分词器效果:

IK分词器

        Elasticsearch默认没有安装IK分词器,需要手工以插件的方式安装到Elasticsearch中,先到Index of: analysis-ik/stable/ 下载和Elasticsearch相同版本的IK分词器elasticsearch-analysis-ik-8.17.3.zip,解压导入到Elasticsearch的elasticsearch-8.17.3\plugins 目录,最后重启Elasticsearch即可。

        IK分词器提供了2种分词算法:1、ik_smart:最少切分  2、ik_max_word:最细粒度划分,在kibana控制台演示如下:

{
  "tokens": [
    {
      "token": "中华人民共和国",
      "start_offset": 0,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "中华人民",
      "start_offset": 0,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 1
    },
    {
      "token": "中华",
      "start_offset": 0,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 2
    },
    {
      "token": "华人",
      "start_offset": 1,
      "end_offset": 3,
      "type": "CN_WORD",
      "position": 3
    },
    {
      "token": "人民共和国",
      "start_offset": 2,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 4
    },
    {
      "token": "人民",
      "start_offset": 2,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 5
    },
    {
      "token": "共和国",
      "start_offset": 4,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 6
    },
    {
      "token": "共和",
      "start_offset": 4,
      "end_offset": 6,
      "type": "CN_WORD",
      "position": 7
    },
    {
      "token": "国",
      "start_offset": 6,
      "end_offset": 7,
      "type": "CN_CHAR",
      "position": 8
    }
  ]
}

                在实际项目中,一般写索引数据时用ik_max_word,查询搜索时用ik_smart。    

Kibana操作

索引操作

        Elasticsearch是使用RESTful风格的http请求访问操作的,请求参数和返回值都是Json格式的,我们可以使用kibana发送http请求操作ES。

        创建索引

        打开kibana控制台,输入如下信息,创建索引product

PUT /product
{
  "mappings": {
    "properties": {
      "id":{"type": "long"},
      "name":{"type": "text","analyzer": "ik_max_word","search_analyzer":"ik_smart"}
    }
  }
}

        删除索引

        删除索引:DELETE product

文档操作

        创建文档:语法如下:POST /索引/_doc/[id值] { "field名":field值 }  ,kibana示例如下:

        查询文档:GET /索引/_doc/id值

        删除文档:DELETE /索引/_doc/id值

文档数据搜索

        基于【文档操作】向索引product中添加文档:1苹果手机,2小米手机,3小米汽车,4奔驰汽车,5小米电脑。

        查询“汽车”后,命中小米汽车和奔驰汽车;查询“小米”后,命中小米汽车,小米手机,小米电脑,符合预期。

Springboot集成Elasticsearch

集成版本说明

        本项目用到框架版本如下:

        1、spring boot :3.1.12

        2、elasticsearch : 8.17.3

        3、JDK :17

        Elasticsearch 8.x 推出后,官方推荐使用 Java REST Client 和 Elasticsearch Client,Spring Data Elasticsearch 也支持这些新的客户端。本文演示基于Spring Data Elasticsearch的方式操作Elasticsearch。操作步骤如下:

添加elasticsearch 依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.gingko</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>elasticsearch</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>3.1.12</spring-boot.version>
    </properties>
    <dependencies>
        <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>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.gingko.elasticsearch.ElasticsearchApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

项目配置elasticsearch

        

        注意:elasticsearch-8.17.3为确保数据传输的安全性,默认通过https来进行通信, 在开发环境中,暂时禁用HTTPS认证,修改:elasticsearch-8.17.3\config\elasticsearch.yml

        

编写测试代码测试

        示例中以产品信息(Product)为例演示,包含id和名称name,其中name以ik_max_word分词器分词,索引建立在product中。

package com.gingko.elasticsearch.entity;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@Data
@Document(indexName = "product")
public class Product {
    @Id
    private String id;
    @Field(type= FieldType.Text,analyzer="ik_max_word",searchAnalyzer = "ik_smart")
    private String name;
}

        基于产品信息实体编写了2个方法,1个是建立索引,1个是根据name关键字查询数据,用到核心的类是ElasticsearchTemplate,建立索引:elasticsearchTemplate.save 方法;查询数据elasticsearchTemplate.search方法。

package com.gingko.elasticsearch.service;

import com.gingko.elasticsearch.entity.Product;
import jakarta.annotation.Resource;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service
public class ProductService {

    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 根据产品信息建立索引
     * @param product
     * @return
     */
    public String saveProduct(Product product) {
        elasticsearchTemplate.save(product);
        return "success";
    }

    /**
     * 根据关键字搜索产品名称
     * @param productName 产品名称关键字
     * @return
     */
    public List<Product> searchProducts(String productName) {
        List<Product> result = new ArrayList<>();//查询结果
        //构造搜索条件,查询name匹配关键字
        Criteria criteria = new Criteria("name").matches(productName);
        Query query = new CriteriaQuery(criteria);
        SearchHits<Product> searchHits = elasticsearchTemplate.search(query, Product.class);
        if(searchHits.hasSearchHits()) {
            searchHits.getSearchHits().forEach(productSearchHit -> {
                result.add(productSearchHit.getContent());
            });
        }
        return result;
    }

}


        对外发布的controller接口如下:

package com.gingko.elasticsearch.controller;

import com.gingko.elasticsearch.entity.Product;
import com.gingko.elasticsearch.service.ProductService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("product")
public class ProductController {

    @Resource
    private ProductService productService;

    @GetMapping("/search")
    public String search(@RequestParam String name) {
        String str = "";
        List<Product> result = productService.searchProducts(name);
        if(result != null && result.size() > 0) {
            for (Product product : result) {
                str += product.getId() + ":" + product.getName() + ",";
            }
        }
        return str;
    }

    @PostMapping("/createProduct")
    public String createProduct(@RequestBody Product product) {
        return this.productService.saveProduct(product);
    }
}

        通过postman 创建了7个document并索引,分别是:1:苹果手机,2:华为手机,3:小米手机,4:奔驰汽车,5:宝马汽车,6:奥迪汽车,7:小米汽车

        通过关键字【小米】查询效果如下图,符合预期。


网站公告

今日签到

点亮在社区的每一天
去签到