专栏首页品茗ITSpringBoot入门建站全系列(二十五)结合Spring-data-elasticsearch进行全文检索

SpringBoot入门建站全系列(二十五)结合Spring-data-elasticsearch进行全文检索

SpringBoot入门建站全系列(二十五)结合Spring-data-elasticsearch进行全文检索

本文主要讲述spring-data-elasticsearch的简单使用。

一、概述

ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。

ES是ElasticSearch的缩写;

ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。

一般公司都是用ELK做日志分析,社区搜索之类的,很少单独使用ElasticSearch。但是单独使用ElasticSearch也很广泛,没有ELK的时候都是这样玩的。

比如我的社区网站(https://www.pomit.cn)就用了ElasticSearch做社区搜索,一开始做搜索的时候,曾有三种方案:

  • Mysql的全文搜索,据说很慢,而且我的mysql版本也不支持中文,还要升级。
  • 搜索引擎的支持,搜索引擎可以传入keyword、site对网站的某个网页做搜索,但是依赖于搜索引擎的收录情况。特别是百度渣渣,求它收录都难,必应还是蛮快的。但是都不够快。
  • ElasticSearch做社区搜索,需要安装ElasticSearch。用了一段时间,感觉还可以。

代码可以在SpringBoot组件化构建https://www.pomit.cn/java/spring/springboot.html中的ElasticSearch组件中查看,并下载。

**如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以<a

href="https://jq.qq.com/?_wv=1027&k=52sgH1J"

target="_blank">

加入我们的java学习圈,点击即可加入

</a>

,共同学习,节约学习时间,减少很多在学习中遇到的难题。**

二、配置

本文假设你已经引入spring-boot-starter-web。已经是个SpringBoot项目了,如果不会搭建,可以打开这篇文章看一看《SpringBoot入门建站全系列(一)项目建立》

2.1 Maven依赖

使用elasticsearch需要引入spring-data-elasticsearch,spring-data-elasticsearch的版本要和安装的elasticsearch保持一致。

版本对应如下:

在这里插入图片描述

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-elasticsearch</artifactId>
	<version>3.1.6.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-commons</artifactId>
	<version>2.1.6.RELEASE</version>
</dependency>

如果spring-data-commons版本不适配当前的spring-data-elasticsearch,还需要额外引入spring-data-commons。

2.2 配置文件

在application.properties 中需要配置elasticsearch的信息,如:

spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300
spring.data.elasticsearch.repositories.enabled=true

我这里只用了一个elasticsearch节点。这里面,

  • spring.data.elasticsearch.cluster-name是elasticsearch的名称。
  • spring.data.elasticsearch.cluster-nodes是集群地址。
  • spring.data.elasticsearch.repositories.enabled开启SpringData的常用写法(类似于Spring-Data-Jpa)

三、Elasticsearch访问数据层

我们直接使用Spring-data-elasticsearch, 一切都会变的特别简单。Spring-data-elasticsearch支持快速查询,也支持@Query之定义查询,要注意它的写法,和elasticsearch原生写法略有不同。

QuestionElasticsearchRepository :

package com.cff.springbootwork.elasticsearch.dao;

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;

import com.cff.springbootwork.elasticsearch.domain.FQuestionElasticssearch;

public interface QuestionElasticsearchRepository extends ElasticsearchRepository<FQuestionElasticssearch, Long> {

	Page<FQuestionElasticssearch> findByCatory(String catory, Pageable pageable);

	@Query("{ \"bool\":{ \"must\":[ { \"multi_match\": { \"query\": \"?0\", \"type\": \"most_fields\", \"fields\": [ \"title\", \"content\" ] } }, { \"match\": { \"catory\": \"?1\" } } ] } } ")
	Page<FQuestionElasticssearch> searchByKeyWordsAndCatory(String keyword, String catory, Pageable pageable);

}

这个写法和Spring-data-jpa基本上一样,应该说Spring-data系列的写法都是类同的。

注意,FQuestionElasticssearch实体需要加上@Document注解指明Elasticssearch中的index和type。

四、测试Elasticssearch

我们定义一个service和web接口来做测试。

QuestionElasticsearchService:

package com.cff.springbootwork.elasticsearch.service;

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.stereotype.Service;
import org.springframework.util.StringUtils;

import com.cff.springbootwork.elasticsearch.dao.QuestionElasticsearchRepository;
import com.cff.springbootwork.elasticsearch.domain.FQuestionElasticssearch;

@Service
public class QuestionElasticsearchService {
	@Autowired
	QuestionElasticsearchRepository questionElasticsearchRepository;

	public Page<FQuestionElasticssearch> pageByOpenAndCatory(Integer page, Integer size, String catory,
			String keyWord) {
		Pageable pageable = PageRequest.of(page, size);
		if (StringUtils.isEmpty(keyWord)) {
			return questionElasticsearchRepository.findByCatory(catory, pageable);

		} else {
			return questionElasticsearchRepository.searchByKeyWordsAndCatory(keyWord, catory, pageable);

		}
	}
}

ElasticsearchRest:

package com.cff.springbootwork.elasticsearch.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.cff.springbootwork.elasticsearch.domain.FQuestionElasticssearch;
import com.cff.springbootwork.elasticsearch.service.QuestionElasticsearchService;

@RestController
@RequestMapping("/elsearch")
public class ElasticsearchRest {

	@Autowired
	QuestionElasticsearchService questionElasticsearchService;

	@RequestMapping(value = "/test", method = { RequestMethod.GET })
	public List<FQuestionElasticssearch> test(@RequestParam(value = "value", required = false) String value) {
		return questionElasticsearchService.pageByOpenAndCatory(0, 10, "Spring专题", value).getContent();
	}
}

五、过程中用到的实体

FQuestionElasticssearch:

package com.cff.springbootwork.elasticsearch.domain;

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

@Document(indexName = "pomit", type = "issue", createIndex = false)
public class FQuestionElasticssearch {
	@Id
	private Long id;
	private String title;
	private String catory;
	private String content;

	public FQuestionElasticssearch() {
	}

	public Long getId() {
		return id;
	}

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

	public void setCatory(String catory) {
		this.catory = catory;
	}

	public String getCatory() {
		return catory;
	}
	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 《你不知道的JavaScript》:利用生成器实现消息传递

    js中生成器函数是一个特殊的函数,具有上一篇中展示出来的“暂停”的执行模式。但它仍然是一个函数,这意味着它仍然有一些基本的特性没有改变。例如它仍然可以接收参数(...

    前端_AWhile
  • V8 Ignition:JS 引擎与字节码的不解之缘(转载)

    首先贴个Javascript性能测试站点,测试并展示了数个 JavaScript 引擎的性能数据:arewefastyet

    Clearlove
  • 《你不知道的JavaScript》:生成器中的生产者和迭代器

    生成器的一种有趣用法是作为一种产生值的方式。而这也是“生成器”这个名称的最初使用场景。前面说过生成器函数每次调用都会创建一个迭代器实例。这个迭代器实例有next...

    前端_AWhile
  • 《你不知道的JavaScript》:迭代器Iterator的背景梳理

    本篇复习下上篇用到的Symbol.iterator,它是ES6内置的十一个Symbol值之一。ES6中规定对象的Symbol.iterator属性指向该对象的默...

    前端_AWhile
  • 解Bug之路-dubbo流量上线时的非平滑问题

    笔者最近解决了一个困扰了业务系统很久的问题。这个问题只在发布时出现,每次只影响一两次调用,相较于其它的问题来说,这个问题有点不够受重视。由于种种原因,使得这个问...

    无毁的湖光-Al
  • Netty自动重连机制的Demo

    官方案例地址:https://netty.io/4.1/xref/io/netty/example/uptime/package-summary.html

    Java猫说
  • Excel VBA解读(160): 数据结构—字典对象的基本操作(续)

    Set dict = CreateObject("Scripting.Dictionary")

    fanjy
  • ELK学习笔记之filebeat合并多行日志示例

    来自Elasticsearch等服务的活动日志通常以时间戳开始,然后是关于特定活动的信息,如下例所示:

    Jetpropelledsnake21
  • 《你不知道的JavaScript》:弄清生成器与迭代器的区别

    这篇将整理下生成器与迭代器的区别。这两个东西初学的时候我是混淆的,尤其《你不知道的Javascript》书中没有进行基础的介绍,我看了之后还特地翻了下其他资料才...

    前端_AWhile
  • ES6中的Class回顾总结三:封装与多态

    在Java中,实现了public完全开放、protected对子类开放、private对自己开放这三种封装的方式。但在ES6中目前并不支持,未来是否会支持也不知...

    前端_AWhile

扫码关注云+社区

领取腾讯云代金券