导入需要的依赖坐标
org.elasticsearch elasticsearch 5.6.8 org.elasticsearch.client transport 5.6.8 org.apache.logging.log4j log4j-to-slf4j 2.9.1 org.slf4j slf4j-api 1.7.24 org.slf4j slf4j-simple 1.7.21 log4j log4j 1.2.12 junit junit 4.12 com.fasterxml.jackson.core jackson-core 2.8.1 com.fasterxml.jackson.core jackson-databind 2.8.1 com.fasterxml.jackson.core jackson-annotations 2.8.1 org.springframework.data spring-data-elasticsearch 3.0.5.RELEASE org.elasticsearch.plugin transport-netty4-client org.springframework spring-test 5.0.4.RELEASE
创建applicationContext.xml配置文件,引入elasticsearch命名空间
编写实体Article
基于spring data elasticsearch注解配置索引、映射和实体的关系
配置映射
@Document文档对象(索引信息、文档类型)
@Id文档主键,是唯一标识
@Field每个文档的字段配置(类型、是否分词、是否存储、分词器)
package com.itheima.domain;
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;
//@Document 文档对象 (索引信息、文档类型 )
@Document(indexName = "blog6",type = "article")
public class Article {
//@Id 文档主键 唯一标识
@Id
private Integer id;
//@Field 每个文档的字段配置(类型、是否分词、是否存储、分词器 )
@Field(type = FieldType.text,index = true,analyzer = "ik_smart",searchAnalyzer = "ik_smart",store = true)
private String title;
@Field(type = FieldType.text,index = true,analyzer = "ik_smart",searchAnalyzer = "ik_smart",store = true)
private String content;
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
@Override
public String toString() {
return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";
}
}
其中,注解解释如下:
@Document(indexName=“blog6”,type=“article”):
indexName:索引的名称(必填项)
type:索引的类型
@Id:主键的唯一标识
@Field(index=true,analyzer=“ik_smart”,store=true,searchAnalyzer=“ik_smart”,type = FieldType.text)
index:是否设置分词
analyzer:存储时使用的分词器
searchAnalyze:搜索时使用的分词器
store:是否存储
type: 数据类型
=======================================
编写Dao
package com.itheima.repository;
import com.itheima.domain.Article;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ArticleRepository extends ElasticsearchRepository {
}
编写Service接口 CRUD操作
package com.itheima.service;
import com.itheima.domain.Article;
import java.util.List;
public interface ArticleService {
// 添加索引
void save(Article article);
//删除索引
void delete(Article article);
//修改索引
void update(Article article);
//查询所有
Iterable findAll();
//分页查询
Iterable findByPage(int page, int size);
//添加多个
void saveAll(List articles);
}
编写service实现类
package com.itheima.service.impl;
import com.itheima.domain.Article;
import com.itheima.repository.ArticleRepository;
import com.itheima.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ArticleServiceImpl implements ArticleService {
@Autowired
private ArticleRepository articleRepository;
//增
public void save(Article article) {
articleRepository.save(article);
}
//删
public void delete(Article article) {
articleRepository.delete(article);
}
//改
public void update(Article article) {
articleRepository.save(article);
}
//添加所有
public void saveAll(List articles) {
articleRepository.saveAll(articles);
}
//查询所有
public Iterable findAll() {
return articleRepository.findAll();
}
//分页查询
public Iterable findByPage(int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size);
return articleRepository.findAll(pageRequest);
}
}
创建测试类SpringDataESTest
package com.itheima;
import com.itheima.domain.Article;
import com.itheima.service.ArticleService;
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.data.domain.PageRequest;
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.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class SpringDataESTest {
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
@Autowired
private ArticleService articleService;
/**
* 创建索引
* 配置映射
*/
@Test
public void createIndex(){
elasticsearchTemplate.createIndex(Article.class);
elasticsearchTemplate.putMapping(Article.class);
}
/**
* 删除索引
* 配置映射
*/
@Test
public void deleteIndex(){
elasticsearchTemplate.deleteIndex(Article.class);
}
/**
* 创建文档
*/
@Test
public void createDocument(){
Article article = new Article();
article.setId(1);
article.setTitle("nihao");
article.setContent("wohao");
articleService.save(article);
}
/**
* 删除文档
*/
public void deleteDoc(){
Article article = new Article();
article.setId(1);
articleService.delete(article);
}
/**
* 更新文档
*/
@Test
public void UpdateDocument(){
Article article = new Article();
article.setId(1);
article.setTitle("hi");
article.setContent("hello");
articleService.update(article);
}
/**
* 添加所有
*/
@Test
public void saveAll(){
List articles = new ArrayList();
for (int i = 0; i < 100; i++) {
Article article = new Article();
article.setId(i);
article.setTitle(i+"标题");
article.setContent(i+"内容");
articles.add(article);
}
articleService.saveAll(articles);
}
/**
* 查询所有
*/
@Test
public void findAll(){
Iterable articles = articleService.findAll();
for (Article article : articles) {
System.out.println(article);
}
}
/**
* 分页查询
*/
@Test
public void findByPage(){
int page = 1;
int size = 5;
Iterable articles = articleService.findByPage(page,size);
for (Article article : articles) {
System.out.println(article);
}
}
/**
* 原生查询
*/
@Test
public void termNativequery(){
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withQuery(QueryBuilders.termQuery("title","搜索"));
nativeSearchQueryBuilder.withPageable(PageRequest.of(1,5));
NativeSearchQuery build = nativeSearchQueryBuilder.build();
List articles = elasticsearchTemplate.queryForList(build, Article.class);
for (Article article : articles) {
System.out.println(article);
}
}
/**
* 原生查询
*/
@Test
public void queryStringQuery(){
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withQuery(QueryBuilders.queryStringQuery("搜索"));
NativeSearchQuery build = nativeSearchQueryBuilder.build();
List articles = elasticsearchTemplate.queryForList(build, Article.class);
for (Article article : articles) {
System.out.println(article);
}
}
}
常用查询命名规则
查询方法测试
dao层实现
package com.itheima.dao;
import com.itheima.domain.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface ArticleRepository extends ElasticsearchRepository {
//根据标题查询
List findByTitle(String condition);
//根据标题查询(含分页)
Page findByTitle(String condition, Pageable pageable);
}
service层实现
public interface ArticleService {
//根据标题查询
List findByTitle(String condition);
//根据标题查询(含分页)
Page findByTitle(String condition, Pageable pageable);
}
service实现类
package com.itheima.service.impl;
import com.itheima.dao.ArticleRepository;
import com.itheima.domain.Article;
import com.itheima.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ArticleServiceImpl implements ArticleService {
@Autowired
private ArticleRepository articleRepository;
public List findByTitle(String condition) {
return articleRepository.findByTitle(condition);
}
public Page findByTitle(String condition, Pageable pageable) {
return articleRepository.findByTitle(condition,pageable);
}
}
测试代码
package com.itheima.test;
import com.itheima.domain.Article;
import com.itheima.service.ArticleService;
import org.elasticsearch.client.transport.TransportClient;
import org.junit.Test;
import org.junit.runner.RunWith;
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.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class SpringDataESTest {
@Autowired
private ArticleService articleService;
@Autowired
private TransportClient client;
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
/**条件查询*/
@Test
public void findByTitle(){
String condition = "版本";
List articleList = articleService.findByTitle(condition);
for(Article article:articleList){
System.out.println(article);
}
}
/**条件分页查询*/
@Test
public void findByTitlePage(){
String condition = "版本";
Pageable pageable = PageRequest.of(2,10);
Page page = articleService.findByTitle(condition,pageable);
for(Article article:page.getContent()){
System.out.println(article);
}
}
}
带高亮显示查询
@Test
public void findByNativeQueryWithHighlighting() {
//创建一个SearchQuery对象
SearchQuery searchQuery = new NativeSearchQueryBuilder()
//设置查询条件,此处可以使用QueryBuilders创建多种查询
.withQuery(QueryBuilders.queryStringQuery("备份节点上没有数据").defaultField("title"))
//还可以设置分页信息
.withPageable(PageRequest.of(1, 5))
//设置高亮条件
.withHighlightFields(new HighlightBuilder.Field("title")
.preTags("")
.postTags("")
)
//创建SearchQuery对象
.build();
//使用模板对象执行查询
elasticsearchTemplate.queryForPage(searchQuery, Article.class, new SearchResultMapper() {
@Override
public AggregatedPage mapResults(SearchResponse searchResponse, Class aClass, Pageable pageable) {
List articles = new ArrayList<>();
//取查询结果
SearchHits hits = searchResponse.getHits();
Iterator iterator = hits.iterator();
//遍历结果集,包括取高亮结果
while (iterator.hasNext()) {
SearchHit searchHit = iterator.next();
Article article = new Article();
//取id
article.setId(Integer.parseInt(searchHit.getSource().get("id").toString()));
//取title,高亮结果
String title = "";
HighlightField highlightField = searchHit.getHighlightFields().get("title");
//如果有高亮结果就取高亮
if (highlightField != null) {
title = highlightField.getFragments()[0].toString();
//如果没有高亮就取原文档中的field
} else {
title = searchHit.getSource().get("title").toString();
}
article.setTitle(title);
//取content
article.setContent(searchHit.getSource().get("content").toString());
//将结果添加到列表
articles.add(article);
}
//创建返回结果对象
AggregatedPage result = new AggregatedPageImpl(articles, pageable, hits.getTotalHits());
return result;
}
}).forEach(a-> System.out.println(a));
}