什么是es?
elasticsearch(简称为es)是一个开源的分布式搜索引擎,用于全文搜索、实时分析和可视化。它建立在apache lucene搜索引擎库的基础上,提供了restful api,支持分布式架构和水平扩展,特别适用于处理大规模的非结构化或半结构化数据。
elasticsearch与传统数据库查询的区别:
-  
搜索引擎特性: elasticsearch是一个搜索引擎,其主要设计目标是支持高效的全文搜索和实时分析。它专注于处理大量文本数据,支持复杂的全文搜索查询,例如模糊搜索、词组匹配、范围查询等。传统数据库主要面向结构化数据,更适用于关系型查询。
 -  
分布式和水平扩展: elasticsearch是分布式的,它可以在多个节点上运行,并能够水平扩展以处理大规模数据。传统数据库通常在单个节点上运行,并且通常需要垂直扩展(增加服务器性能)来处理更大的负载。
 -  
schema-less(无模式): elasticsearch是无模式的,意味着你不需要在索引中预定义数据结构。你可以直接插入数据,elasticsearch会根据数据自动推断其类型。传统数据库需要在创建表时定义模式。
 -  
实时性: elasticsearch提供实时索引和搜索功能,数据几乎立即可用于搜索。传统数据库的实时性可能受到数据复制和索引的影响。
 -  
多语言支持: elasticsearch支持多种查询语言,例如查询字符串、dsl(domain specific language)等,使其更易于使用和集成。传统数据库通常使用sql。
 
要在spring boot项目中集成elasticsearch,首先需要添加相应的依赖,然后配置elasticsearch的连接信息,最后通过spring data elasticsearch或者elasticsearch的java rest客户端来与elasticsearch进行交互。
springboot整合elasticsearch的步骤:
0.代码层级结构

1. 添加依赖
在pom.xml中添加spring data elasticsearch依赖:
 <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-data-elasticsearch</artifactid>
 </dependency> 
2. 配置elasticsearch连接信息
在application.properties或(application.yml)中配置elasticsearch连接信息,如下:
spring.elasticsearch.uris=http://localhost:9200 
spring:
  elasticsearch:
    uris: http://localhost:9200
 
如果elasticsearch没有设置用户名和密码,这可能就足够了。如果需要认证,可以使用以下配置:
spring.elasticsearch.username=your_username
spring.elasticsearch.password=your_password 
spring:
  elasticsearch:
    uris: http://localhost:9200
    username:your_username
    password:your_password 
3. 创建实体类
创建一个简单的实体类,使用@document注解指定索引和类型:
import lombok.data;
import org.springframework.data.annotation.id;
import org.springframework.data.elasticsearch.annotations.document;
/**
 * @document(indexname = "user-demo") 索引名称为user-demo
 * */
@data
@document(indexname = "user-demo")
public class user {
    @id
    private string id;
    private string username;
    private string address;
    private integer age;
    private string gender;
}
 
4. 使用spring data elasticsearch进行操作
创建一个usermapper接口,继承自elasticsearchrepository:
import com.example.demoes.entity.user;
import org.springframework.data.domain.page;
import org.springframework.data.domain.pageable;
import org.springframework.data.elasticsearch.repository.elasticsearchrepository;
import org.springframework.stereotype.repository;
import java.util.list;
/**
 * 这些方法的名称遵循一种命名约定,这种约定将方法名中的关键词(如 findby、like、ignorecase 等)与实体类(user)的属性名相关联。
 * 这样,spring data elasticsearch 可以根据方法名自动生成相应的查询。
 *
 * 在spring data elasticsearch中,查询方法的命名约定依赖于一些关键词和命名规范,这些关键词用于描述要执行的查询操作。以下是一些常见的关键词和它们的含义:
 *
 *     findby:指定查询的条件的前缀,后面通常跟随实体类的属性名。例如,findbyusername 表示要根据用户名进行查询。
 *
 *     like:用于模糊查询,通常与属性名一起使用。例如,findbyusernamelike 表示要进行用户名的模糊查询。
 *
 *     ignorecase:用于不区分大小写的查询,通常与属性名一起使用。例如,findbyusernameignorecase 表示不区分大小写地查询用户名。
 *
 *     containing:用于包含查询,通常与属性名一起使用。例如,findbyusernamecontaining 表示包含指定内容的查询。
 *
 *     and 和 or:用于构建复合查询条件。例如,findbyusernameandage 表示根据用户名和年龄进行查询。
 *
 *     orderby:用于指定结果的排序方式。例如,findbyageorderbyusernamedesc 表示根据年龄查询并按用户名降序排序。
 *
 *     page 和 iterable:用于指定查询结果的返回类型。例如,page<user> 表示返回分页结果,iterable<user> 表示返回一个列表。
 *
 *     其他属性名:您可以根据实体类的属性名来定义查询条件。例如,如果实体类有一个属性为 email,您可以编写 findbyemail 方法来根据邮箱进行查询。
 * */
@repository
public interface usermapper extends elasticsearchrepository<user,string> {
    /**
     *自定义查询
     * */
    list<user> findbyaddresslikeignorecaseorderbyagedesc(string address);
    page<user> findbyusernamecontaining(string username, pageable page);
    user findbyage(integer age);
    list<user> findbygender(string gender);
    long count();
    boolean existsbyid();
}
 
5.测试
在测试中使用spring boot的@springboottest注解,来验证elasticsearch是否正常工作。
import com.example.demoes.entity.user;
import com.example.demoes.mapper.usermapper;
import org.junit.jupiter.api.test;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.boot.test.context.springboottest;
import org.springframework.data.domain.page;
import org.springframework.data.domain.pagerequest;
import org.springframework.data.elasticsearch.core.elasticsearchresttemplate;
import java.util.*;
@springboottest
class demoesapplicationtests {
    //    @resource
    @autowired
    private usermapper usermapper;
    @autowired
    private elasticsearchresttemplate elasticsearchresttemplate;
    @test
    void add() {
        for (int i = 2; i < 11; i++) {
            user user = new user();
            user.setid(i + "");
            user.setusername("zhangsan" + i);
            user.setgender("男");
            user.setage(i + i);
            user.setaddress("河北省" + i);
            //直接将数据保存到es中,索引名称为user-demo,在user对象中设置的
            //通过kibana进行查询get /user-demo/_search
            user save = usermapper.save(user);
            system.out.println("save = " + save);
        }
    }
    @test
    void delete() {
        string id = "9";
        usermapper.deletebyid(id);
    }
    @test
    void update() {
        user updateuser = new user();
        updateuser.setid("9");
        updateuser.setusername("lisi");
        updateuser.setgender("女");
        updateuser.setaddress("北京市");
        updateuser.setage(39);
        user save = usermapper.save(updateuser);
        system.out.println("save = " + save);
    }
    @test
    void find() {
        //模糊查询。精确查询
        iterable<user> all = usermapper.findall();
        list<user> list = new arraylist<>();
        for (user user : all) {
            list.add(user);
        }
        // 使用collections.sort方法按照用户的id进行排序
//        collections.sort(list, comparator.comparing(user::getid));
        // 使用自定义比较器按照用户的id进行排序
        collections.sort(list, new comparator<user>() {
            @override
            public int compare(user user1, user user2) {
                // 假设id是字符串类型
                return user1.getusername().compareto(user2.getusername());
            }
        });
        // 使用流(stream)按照用户的id进行排序
        /*list<user> sortedlist = list.stream()
                .sorted(comparator.comparing(user::getid))
                .collect(collectors.tolist());*/
        // 现在list中的用户已按照id升序排列
        for (user user : list) {
            system.out.println("user = " + user);
        }
    }
    @test
    void findbyid() {
        //注意这里的id是字符串类型,然后usermapper中继承的id也必须是string类型
        optional<user> byid = usermapper.findbyid("4");
        system.out.println("byid = " + byid);
    }
    @test
    void findcount() {
        long count = usermapper.count();
        system.out.println("count 数 " + count);
    }
    @test
    void existsbyid() {
        system.out.println("id是否存在: " + usermapper.existsbyid("1"));
    }
    @test
    void findbyidall() {
        arraylist<string> ids = new arraylist<>();
        ids.add("3");
        ids.add("5");
        ids.add("4");
        ids.add("66");
        //通过ids(集合)进行查询对应的user集合对象
        iterable<user> allbyid = usermapper.findallbyid(ids);
        for (user user : allbyid) {
            system.out.println("user = " + user);
        }
    }
    /**
     * 自定义查询
     */
    @test
    void findbyusernamelike() {
        //模糊查询,会通过命名规范进行一个查询
        list<user> addr = usermapper.findbyaddresslikeignorecaseorderbyagedesc("河北");
        system.out.println("addr = " + addr);
        page<user> page = usermapper.findbyusernamecontaining("4", pagerequest.of(0, 100));
        system.out.println("page = " + page.getcontent());
        user zhanglist = usermapper.findbyage(16);
        system.out.println("user = " + zhanglist);
        list<user> gender = usermapper.findbygender("女");
        system.out.println("gender = " + gender);
    }
 
以上步骤是一个简单的spring boot集成elasticsearch的示例。你可以根据你的实际需求进行更复杂的配置和操作。
            
                                            
发表评论