环境
1.elasticsearch 7.8.0
2.springboot 2.4.0
3.JDK 8
集成配置
1.pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
</parent>
<dependencies>
<!-- ES依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
2.application.yml
# ES配置文件会读取此处的host及port创建ES连接对象
elasticsearch:
host: 127.0.0.1
port: 9200
3.ElasticSearch配置文件
/**
* ElasticSearch配置文件,用于获取ES连接对象
*/
import lombok.Data;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
@ConfigurationProperties(value = "elasticsearch") // 匹配application.yml中elasticsearch开头的配置,并为下面的host,port赋值
@Configuration
@Data
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
private String host;
private Integer port;
@Override
public RestHighLevelClient elasticsearchClient() {
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
return restHighLevelClient;
}
}
4.定义ElasticSearch实体
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
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
@AllArgsConstructor
@NoArgsConstructor
@Document(indexName = "product", shards = 3, replicas = 1) // indexName指定索引名称、shards指定索引分片数、replicas指定分片数
public class Product {
@Id
private Long id; /* ID */
@Field(type = FieldType.Text,analyzer = "ik_max_word") /* text 分词,analyzer = "ik_max_word" 指定分词器类型 */
private String title; /* 标题 */
@Field(type = FieldType.Keyword) /* keyword 不分词 */
private String category; /* 品牌 */
@Field(type = FieldType.Double)
private Double price; /* 价格 */
@Field(type = FieldType.Keyword, index = false) // index = false代表不能用images查询
private String images; /* 图片 */
}
5.定义数据持久层Dao
import cn.cdjs.entity.Product;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
* ES数据持久层
* ElasticsearchRepository<Product,Long>
* Product:指定操作的ES文档对象
* Long:指定操作的ES文档对象主键类型
*/
@Repository
public interface IProductDao extends ElasticsearchRepository<Product,Long> {
}
6.启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}
7.测试类
import cn.cdjs.dao.IProductDao;
import cn.cdjs.entity.Product;
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.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticSearchTest {
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
@Autowired
private IProductDao productDao;
/** ======================================== 索引相关操作 ========================================*/
@Test
public void createIndex(){
// 项目启动时系统会自动读取ES配置的实体类。如果ES索引库中没用该索引则自动创建
}
/* 删除索引 */
@Test
public void deleteIndex(){
boolean flag = elasticsearchRestTemplate.deleteIndex(Product.class);
System.out.println("删除索引结果:" + flag);
}
/** ======================================== 文档相关操作 ========================================*/
/* 保存数据 */
@Test
public void save(){
Product product = new Product();
product.setId(2L);
product.setCategory("手机");
product.setImages("http://www.huawei.com");
product.setPrice(2999.0);
product.setTitle("华为手机");
// 保存数据
productDao.save(product);
}
/* 更新数据 */
@Test
public void update(){
Product product = new Product();
product.setId(2L);
product.setCategory("手机");
product.setImages("http://www.xiaomi.com");
product.setPrice(6999.0);
product.setTitle("小米手机");
// 更新数据,若ID相同调用save方法则更新,ID不同则新增
productDao.save(product);
}
/* 根据ID查询数据 */
@Test
public void findById(){
Product product = productDao.findById(2L).get();
System.out.println("查询ID为2的数据:" + product);
}
/* 查询索引下的所有数据 */
@Test
public void findAll(){
Iterable<Product> products = productDao.findAll();
for (Product product:products) {
System.out.println(product);
}
}
/* 删除数据 */
@Test
public void delete(){
Product product = new Product();
product.setId(2L);
productDao.delete(product); // 或调用productDao.deleteById(2L);
}
/* 批量新增 */
@Test
public void saveAll(){
List<Product> list = new ArrayList<>();
for (int i = 3;i <= 10;i++){
Product product = new Product();
product.setId(Long.valueOf(i));
product.setCategory("手机");
product.setImages("http://www.xiaomi.com");
product.setPrice(6999.0 + i);
product.setTitle("[" + i +"]" + "小米手机");
list.add(product);
}
productDao.saveAll(list);
}
/* 分页查询 */
@Test
public void findByPageable(){
// 设置排序方式(根据ID,降序排)
Sort sort = Sort.by(Sort.Direction.DESC, "id");
// 当前页
int currentPage = 0;
// 每页条数
int pageSize = 5;
// 设置分页查询条件
PageRequest pageRequest = PageRequest.of(currentPage, pageSize, sort);
// 分页查询
Iterable<Product> products = productDao.findAll(pageRequest);
for (Product product:products) {
System.out.println(product);
}
}
/** ======================================== 文档搜索操作 ========================================*/
/* term查询 */
@Test
public void termQuery(){
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");
// 查询category 为“手机”的数据
Iterable<Product> products = productDao.search(termQueryBuilder);
for (Product product:products) {
System.out.println(product);
}
}
/* term查询 + 分页 */
@Test
public void termQueryByPage(){
int currentPage = 0;
int pageSize = 5;
// 构建trem条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");
// 构建排序条件
Sort sort = Sort.by(Sort.Direction.DESC, "price");
// 构建分页 + 排序
PageRequest pageRequest = PageRequest.of(currentPage, pageSize, sort);
// 组装查询
Page<Product> products = productDao.search(termQueryBuilder, pageRequest);
for (Product product:products) {
System.out.println(product);
}
}
}
说明:可使用QueryBuilders构建不同的查询条件;