Elaticsearch,简称为es, es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检 索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用Java开发并使用 Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏 Lucene的复杂性,从而让全文搜索变得简单。
接下来本次将演示如何在springboot中整合es的功能,本文用的es版本是5.6.8,由于使用的es版本比较低,所以springbot版本为2.1.16,
1.springboot配置文件配置spring:
data:
elasticsearch:
cluster-name: my-application
cluster-nodes: 192.168.75.128:9300
注意连接es的端口是9300,不是web端口9200,
2.依赖配置3.编写实体类Article4.0.0 org.springframework.boot spring-boot-starter-parent2.1.16.RELEASE com.kkb springboot-es0.0.1-SNAPSHOT springboot-es springboot-es 1.8 org.springframework.boot spring-boot-starter-data-elasticsearchorg.springframework.boot spring-boot-starter-testtest org.springframework.boot spring-boot-maven-plugin
@Document(indexName = "lxs_blog", type = "article")
public class Article {
@Id
@Field(type = FieldType.Long,store = true)
private Long id;
@Field(type = FieldType.Text,store = true,analyzer = "ik_smart")
private String title;
@Field(type = FieldType.Text,store = true,analyzer = "ik_smart")
private String content;
@Override
public String toString() {
return "Article{" +
"id=" + id +
", title='" + title + ''' +
", content='" + content + ''' +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
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;
}
}
@Document注解是声明索引和类型
@Id 是主键 ,@Field相当于配置的mapping,例如字段的类型,是否持久化,使用什么分词器
4.编写Dao方法命名规则查询的基本语法findBy + 属性 + 关键词 + 连接符
public interface ArticleDAO extends ElasticsearchRepository {
List findByTitleLike(String title);
List findByTitle(String title);
List findByTitleOrContent(String title, String content);
List findByTitleLikeOrContent(String title, String content);
List findByTitleOrContent(String title, String content, Pageable pageable);
}
DAO接口只需要继承ElasticsearchRepository
package com.kkb.springbootes;
import com.kkb.springbootes.dao.ArticleDAO;
import com.kkb.springbootes.domain.Article;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
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.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootEsApplicationTests {
@Autowired
private ArticleDAO dao;
@Autowired
private ElasticsearchTemplate template;
@Test
public void contextLoads() {
}
@Test
public void createIndex() {
//这一步在Article里面已经配置好了mapping,所以就可以直接创建一个带mapping的索引
template.createIndex(Article.class);
//单独的配置mapping方法
//template.putMapping(Article.class);
}
@Test
public void addDocument() throws Exception {
for (int i = 1; i <= 20; i++) {
//创建一个Article对象
Article article = new Article();
article.setId(new Long(i));
article.setTitle("女护士路遇昏迷男子跪地抢救:救人是职责更是本能" + i);
article.setContent("这是一个美丽的女护士妹妹" + i);
//把文档写入索引库
dao.save(article);//保存也是修改
}
}
@Test
public void deleteDocumentById() {
dao.deleteById(3L);
//全部删除
//dao.deleteAll();
}
@Test
public void findAll() {
dao.findAll().forEach(System.out::println);
}
@Test
public void findById() {
System.out.println(dao.findById(1L));
}
@Test
public void findByTitle() {
//不加like没有分词效果,内部调用的是term,没有分词的效果
dao.findByTitle("女护士").forEach(System.out::println);
}
@Test
public void findByTitleLike() {
dao.findByTitleLike("美丽的女护士").forEach(System.out::println);//内部调用的是match
}
@Test
public void findByTitleOrContent() {
dao.findByTitleOrContent("女护士","女护士").forEach(System.out::println);
}
@Test
public void findByTitleLikeOrContent() {
dao.findByTitleLikeOrContent("美丽女护士","男护士").forEach(System.out::println);
}
@Test
public void findByTitleOrContentPage() {
//page第一个参数,是从零开始的页面索引。0表示第一页,1表示第二页
Pageable pageable = PageRequest.of(0, 5);
dao.findByTitleOrContent("女护士","女护士",pageable).forEach(System.out::println);
}
@Test
public void testNativeSearchQuery() {
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.queryStringQuery("女护士").defaultField("title"))
.withPageable(PageRequest.of(0,5))
.build();
List articles = template.queryForList(query, Article.class);
articles.forEach(System.out::println);
// articles.getClass().getName();
}
}
其中一个分页测试的查询结果



