SpringBoot 整合 ElasticSearch 之 ElasticsearchRepository 的 CRUD、分页接口

一、前言

SpringBoot 整合 ElasticSearch 之 ElasticsearchRepository 的 CRUD、分页接口_第1张图片

前面使用了 SpringBoot 整合了 Solr: [增删改查] SpringBoot 整合 Solr 实现 CRUD、分页接口、高亮显示
眼下有一个比 Solr 还火热的 ElasticSearch,主要是用于大数据、分布式系统中,顺便使用 SpringBoot 来整合

Elasticsearch是一个基于Lucene的搜索服务器。
它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

使用的方式主要两种:
① 一种是经过 SpringData 封装过的,直接在 dao 接口继承 ElasticsearchRepository 即可
② 一种是经过 Spring 封装过的,直接在 Service/Controller 中引入该 bean 即可

	@Autowired
	ElasticsearchTemplate elasticsearchTemplate;

二、代码

2018.7.14更新,代码已经放到 github 上了:https://github.com/larger5/SpringBoot_ElasticSearch_base.git

1、entity

package com.cun.entity;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

/**
 * 加上了@Document注解之后,默认情况下这个实体中所有的属性都会被建立索引、并且分词
 * @author linhongcun
 *
 */
//http://120.79.197.131:9200/product
@Document(indexName = "product", type = "book")
public class Book {
	@Id
	String id;
	String name;
	String message;
	String type;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

}

2、dao 接口

package com.cun.dao;

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import com.cun.entity.Book;

public interface BookDao extends ElasticsearchRepository<Book,String>{

}

3、Controller

① ElasticsearchRepository
package com.cun.controller;

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

import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.cun.dao.BookDao;
import com.cun.entity.Book;

import springfox.documentation.swagger2.annotations.EnableSwagger2;

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

	@Autowired
	private BookDao bookDao;

	/**
	 * 1、查  id
	 * @param id
	 * @return
	 */
	@GetMapping("/get/{id}")
	public Book getBookById(@PathVariable String id) {
		return bookDao.findOne(id);
	}

	/**
	 * 2、查  ++:全文检索(根据整个实体的所有属性,可能结果为0个)
	 * @param q
	 * @return
	 */
	@GetMapping("/select/{q}")
	public List<Book> testSearch(@PathVariable String q) {
		QueryStringQueryBuilder builder = new QueryStringQueryBuilder(q);
		Iterable<Book> searchResult = bookDao.search(builder);
		Iterator<Book> iterator = searchResult.iterator();
		List<Book> list = new ArrayList<Book>();
		while (iterator.hasNext()) {
			list.add(iterator.next());
		}
		return list;
	}

	/**
	 * 3、查   +++:分页、分数、分域(结果一个也不少)
	 * @param page
	 * @param size
	 * @param q
	 * @return 
	 * @return
	 */
	@GetMapping("/{page}/{size}/{q}")
	public List<Book> searchCity(@PathVariable Integer page, @PathVariable Integer size, @PathVariable String q) {

		// 分页参数
		Pageable pageable = new PageRequest(page, size);

		// 分数,并自动按分排序
		FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery()
				.add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("name", q)),
						ScoreFunctionBuilders.weightFactorFunction(1000)) // 权重:name 1000分
				.add(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("message", q)),
						ScoreFunctionBuilders.weightFactorFunction(100)); // 权重:message 100分

		// 分数、分页
		SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable)
				.withQuery(functionScoreQueryBuilder).build();

		Page<Book> searchPageResults = bookDao.search(searchQuery);
		return searchPageResults.getContent();

	}

	/**
	 * 4、增
	 * @param book
	 * @return
	 */
	@PostMapping("/insert")
	public Book insertBook(Book book) {
		bookDao.save(book);
		return book;
	}

	/**
	 * 5、删 id
	 * @param id
	 * @return
	 */
	@DeleteMapping("/delete/{id}")
	public Book insertBook(@PathVariable String id) {
		Book book = bookDao.findOne(id);
		bookDao.delete(id);
		return book;
	}

	/**
	 * 6、改
	 * @param book
	 * @return
	 */
	@PutMapping("/update")
	public Book updateBook(Book book) {
		bookDao.save(book);
		return book;
	}

}

② elasticsearchTemplate(简单使用)
package com.cun.controller;

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

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 简单使用 elasticsearchTemplate
 * @author linhongcun
 *
 */
@RestController
@RequestMapping("/template")
public class BookControllerTemplate {

	@Autowired
	ElasticsearchTemplate elasticsearchTemplate;

	/**
	 * 查询所有
	 * @throws Exception
	 */
	@GetMapping("/all")
	public List<Map<String, Object>> searchAll() throws Exception {
		//这一步是最关键的
		Client client = elasticsearchTemplate.getClient();
		// @Document(indexName = "product", type = "book")
		SearchRequestBuilder srb = client.prepareSearch("product").setTypes("book");
		SearchResponse sr = srb.setQuery(QueryBuilders.matchAllQuery()).execute().actionGet(); // 查询所有
		SearchHits hits = sr.getHits();
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for (SearchHit hit : hits) {
			Map<String, Object> source = hit.getSource();
			list.add(source);
			System.out.println(hit.getSourceAsString());
		}
		return list;
	}


}

4、yml

server:
  context-path: /
  port: 80
spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch #默认即为 elasticsearch
      cluster-nodes: 120.79.197.131:9300 #配置es节点信息,逗号分隔,如果没有指定,则启动ClientNode

5、pom

		
			org.springframework.boot
			spring-boot-starter-data-elasticsearch
		

三、其他

使用 Swagger 生成接口测试页面,所有接口均经过测试,完全没有问题!

		
		<dependency>
			<groupId>io.springfoxgroupId>
			<artifactId>springfox-swagger2artifactId>
			<version>2.7.0version>
		dependency>

		
		<dependency>
			<groupId>io.springfoxgroupId>
			<artifactId>springfox-swagger-uiartifactId>
			<version>2.6.1version>
		dependency>

SpringBoot 整合 ElasticSearch 之 ElasticsearchRepository 的 CRUD、分页接口_第2张图片

四、小结

Ⅰ、应用

Github、StackOverFlow 等网站都是使用 ElasticSearch 作为搜索引擎的

Ⅱ、参考文章:

① springboot整合elasticsearch入门例子
②Spring Boot 整合Elasticsearch
③spring 操作elasticsearch
④ ElasticSearch搜索实例含高亮显示及搜索的特殊字符过滤
⑤ docker环境 快速使用elasticsearch-head插件

Ⅲ、其他知识须知

9300端口: ES节点之间通讯使用
9200端口: ES节点 和 外部 通讯使用

你可能感兴趣的:(SpringBoot 整合 ElasticSearch 之 ElasticsearchRepository 的 CRUD、分页接口)