Springboot实战之spring-boot-starter-data-elasticsearch搭建ES搜索接口

本文档详细介绍了如何使用Springboot 2.6.4集成spring-boot-starter-data-elasticsearch来搭建Elasticsearch7.15.2的搜索接口。首先准备Elasticsearch和Kibana环境,创建索引book并配置映射,然后通过Springboot创建项目,添加依赖,配置application.properties,创建BookBean、BookRepository、BookService和BookController。最后展示了如何保存、查询和搜索数据。

Springboot实战之spring-boot-starter-data-elasticsearch搭建ES搜索接口

本教程是本人亲自实战的,然后运行起来的全部步骤。

准备工作

环境
Elasticsearch 7.15.2
Kibana 7.15.2
springboot 2.6.4 以及对应的spring-boot-starter-web和spring-boot-starter-data-elasticsearch
fastjson 1.2.97

  1. 安装好Elasticsearch7.15.2以及对应的Kibana。
  2. Springboot Start 新建项目

在Kibana中新建索引book

使用 devtools 创建

# 新增索引
PUT book
{
  "settings" : {
      "number_of_shards" : 5,
      "number_of_replicas" : 0,
      "refresh_interval": "5s", 
      "index.mapping.ignore_malformed": true 
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_max_word"
      },
      "author": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_max_word"
      },
      "postDate": {
        "type": "keyword"
      }
    }
  }
}

number_of_shards 数据分片 默认为5
number_of_replicas 数据备份数,如果只有一台机器,建议设置为0,避免索引一直处于yellow状态

查看是否创建成功

HEAD book

返回如下,即为创建索引成功

200 - OK

搜素 book 里面的信息

POST book/_search
{
  "from": 0,
  "size": 20
}

新建springboot项目

Springboot Start 新建项目
在这里插入图片描述
点击generate就会获取一个zip的包。这个就是生成的项目哦。

打开项目

项目完成之后的完整目录:
在这里插入图片描述

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.wumeng</groupId>
	<artifactId>esapi</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>esapi</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.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.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>


		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.79</version>
		</dependency>



	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>


	<repositories>
		<repository>
			<id>ali-maven</id>
			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
		</repository>
	</repositories>

</project>

application.properties 文件

# ELASTICSEARCH (ElasticsearchProperties)

# Whether to enable Elasticsearch repositories.
spring.data.elasticsearch.repositories.enabled=true

spring.elasticsearch.uris=http://192.168.0.119:9200
spring.elasticsearch.username=elastic
spring.elasticsearch.password=12345678
spring.elasticsearch.socket-timeout=30

修改成自己的用户名和密码哦

BookBean.java 文件

import lombok.Builder;
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
@Builder
@Document(indexName = "book")
public class BookBean {
    private @Id String id;

    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String title;

    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String author;

    private String postDate;

    public  BookBean(){}

    public BookBean(String id, String title, String author, String postDate) {
        this.id = id;
        this.title = title;
        this.author = author;
        this.postDate = postDate;
    }
}

BookRepository.java 文件

import com.wumeng.esapi.model.BookBean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface BookRepository extends ElasticsearchRepository<BookBean,String> {

    //Optional<BookBean> findById(String id);

    Page<BookBean> findByAuthor(String author, Pageable pageable);

    Page<BookBean> findByTitle(String title, Pageable pageable);
    
    @Query("{\"match\": {\"title\": {\"query\": \"?0\"}}}")
    Page<BookBean> findByTitle_custom(String keyword, Pageable pageable);

}

BookService.java 文件

import com.wumeng.esapi.model.BookBean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

import java.util.List;
import java.util.Optional;

public interface BookService {
    Optional<BookBean> findById(String id);

    BookBean save(BookBean blog);

    void delete(BookBean blog);

    Optional<BookBean> findOne(String id);

    List<BookBean> findAll();

    Page<BookBean> findByAuthor(String author, PageRequest pageRequest);

    Page<BookBean> findByTitle(String title, PageRequest pageRequest);

    List<BookBean> searchByKeyword(String keyword, PageRequest pageRequest);

}

BookServiceImpl.java 文件

import com.wumeng.esapi.repository.BookRepository;
import com.wumeng.esapi.model.BookBean;
import com.wumeng.esapi.service.BookService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

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

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    @Qualifier("bookRepository")
    private BookRepository bookRepository;

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;


    @Override
    public Optional<BookBean> findById(String id) {
        //CrudRepository中的方法
        return bookRepository.findById(id);
    }

    @Override
    public BookBean save(BookBean blog) {
        return bookRepository.save(blog);
    }

    @Override
    public void delete(BookBean blog) {
        bookRepository.delete(blog);
    }

    @Override
    public Optional<BookBean> findOne(String id) {
        return bookRepository.findById(id);
    }

    @Override
    public List<BookBean> findAll() {
        return (List<BookBean>) bookRepository.findAll();
    }

    @Override
    public Page<BookBean> findByAuthor(String author, PageRequest pageRequest) {
        return bookRepository.findByAuthor(author,pageRequest);
    }

    @Override
    public Page<BookBean> findByTitle(String title, PageRequest pageRequest) {
        return bookRepository.findByTitle(title,pageRequest);
    }


//    @Override
//    public Page<BookBean> searchByKeyword(String keyword, PageRequest pageRequest) {
//        return bookRepository.searchByKeyword(keyword, pageRequest);
//    }

    @Override
    public List<BookBean> searchByKeyword(String keyword, PageRequest pageRequest) {



        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        // 查询必须满足的条件
//        boolQueryBuilder.must(QueryBuilders.termQuery("studentSex", "女"));

        // 查询可能满足的条件
//        boolQueryBuilder.should(QueryBuilders.termQuery("gradeNumber", "一年级"));
//        boolQueryBuilder.should(QueryBuilders.termQuery("gradeNumber", "二年级"));
//        boolQueryBuilder.should(QueryBuilders.termQuery("gradeNumber", "三年级"));//精确
        boolQueryBuilder.should(QueryBuilders.matchQuery("title",keyword));//模糊
        boolQueryBuilder.should(QueryBuilders.matchQuery("author",keyword));
        // 设置在可能满足的条件中,至少必须满足其中1条
//        boolQueryBuilder.minimumShouldMatch(1);

        // 必须不满足的条件
//        boolQueryBuilder.mustNot(QueryBuilders.termQuery("age", 8));


        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //查询
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        //排序
        nativeSearchQueryBuilder.withSorts(SortBuilders.fieldSort("postDate").order(SortOrder.ASC));
        //分页
        nativeSearchQueryBuilder.withPageable(pageRequest);
		
		//搜索
        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        SearchHits<BookBean> productHits = this.elasticsearchOperations.search(nativeSearchQuery, BookBean.class, IndexCoordinates.of("book"));

        List<BookBean> productMatches = new ArrayList<BookBean>();
        productHits.forEach(searchHit->{
            productMatches.add(searchHit.getContent());
        });

        return productMatches;
    }
}

BookController.java 文件


import com.alibaba.fastjson.JSON;
import com.wumeng.esapi.service.BookService;
import com.wumeng.esapi.model.BookBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("book")
public class BookController {

    @Autowired
    private BookService bookService;

    @RequestMapping("/id/{id}")
    @ResponseBody
    public BookBean getBookById(@PathVariable String id){
        Optional<BookBean> opt =bookService.findById(id);
        BookBean book=opt.get();
        System.out.println(book);
        return book;
    }

    @RequestMapping("/save")
    @ResponseBody
    public String Save(){
        BookBean book=new BookBean("1","ES入门教程","你刚回来了","2022-03-09");
        System.out.println(book);
        bookService.save(book);

        book=new BookBean("2","ES入门教程","你刚回来了","2022-03-09");
        System.out.println(book);
        bookService.save(book);

        book=new BookBean("3","ES入门教程","你刚回来了","2022-03-09");
        System.out.println(book);
        bookService.save(book);

        return "Save success.";

    }
    @RequestMapping("/search/{keyword}")
    @ResponseBody
    public String searchBookByKeyWord(@PathVariable String keyword){
        List<BookBean> list = bookService.searchByKeyword(keyword,PageRequest.of(0,200));
        System.out.println(list);
        return JSON.toJSONString(list);
    }

}

运行项目,跑起来。

插入信息

访问地址:http://127.0.0.1:8080/book/save

Save success.
根据id查询信息

访问地址:http://127.0.0.1:8080/book/id/1

{"id":"1","title":"ES入门教程","author":"你刚回来了","postDate":"2022-03-09"}
模糊查询titie 和author

访问地址:http://127.0.0.1:8080/book/search/ES

[{"author":"你刚回来了","id":"2","postDate":"2022-03-09","title":"ES入门教程"},{"author":"你刚回来了","id":"1","postDate":"2022-03-09","title":"ES入门教程"}]

此次,项目简单基本雏形已经有了,可以继续开发其他任务了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WMSmile

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值