0
点赞
收藏
分享

微信扫一扫

SpringBoot 整合 ES (六)


我看到希望,哪怕只有微小的一束光,我也会拼尽全力去寻找

上一章简单介绍了 ES的Java API 操作(五), 如果没有看过,请观看上一章

一. SpringBoot 整合ES

我们上一章节使用 Java API, 发现操作是很复杂的, 如果可以像操作 jpa, redis 一样, 提供对应的 JpaRestTemplate ,RedisRestTemplate 操作就好了.

其实也提供了相应的信息.

一. 一. pom.xml 引入依赖

<!--引入 spring-data-elasticsearch-->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>

一.二. 配置RestHighLevelClient

一.二.一. application.yml 配置 host 和port

elasticsearch:
  host: 127.0.0.1
  port: 9200

一.二.一 配置 ES 的 Config

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.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.stereotype.Component;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 配置 ES
 *
 * @author yuejianli
 * @date 2022-08-18
 */
@Component
@ConfigurationProperties("elasticsearch")
@Data
public class EsConfig extends AbstractElasticsearchConfiguration {
	private String host;
	private Integer port;
	
	@Override
	public RestHighLevelClient elasticsearchClient() {
		RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(host, port));
		return new RestHighLevelClient(restClientBuilder);
	}
}

一.三 配置相应的实体 Product

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;
import lombok.Data;

/**
 * 商品
 *
 * @author yuejianli
 * @date 2022-08-18
 */
@Data
@Document(indexName = "product")
public class Product {
	@Id
	private Integer id;
	@Field(type = FieldType.Text, analyzer = "ik_max_word")
	private String title;
	@Field(type = FieldType.Text, analyzer = "ik_max_word")
	private String author;
	@Field(type = FieldType.Keyword)
	private String category;
	@Field(type = FieldType.Double)
	private Double price;
	@Field(type = FieldType.Keyword, index = false)
	private String image;
}

@Document, 指定索引名

@Id, 必须要有 id, 是全局唯一标识, 等同于 es 中的 _id

@Field 标识属性,type 指定 字段数据类型, analyzer 分词器类型, index 是否是索引, 默认为索引.

Keyword 短语, 不进行分词。

一.四 创建对应实体的 Repository

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
/**
 * 用途描述
 *
 * @author yuejianli
 * @date 2022-08-18
 */
@Repository
public interface ProductRepository extends ElasticsearchRepository<Product, Integer> {

}

是不是很像 JPA 了 ?

一.五 执行,测试整合验证

@Test
	public void createIndexTest() {
		log.info(">>>> 创建索引成功");
	}

实体 Product, 标记了 Document 索引, 如果没有索引的话,会自动创建索引 product

如果已经存在了索引,则不会自动创建.

SpringBoot 整合 ES (六)_spring

二. Repository 文档操作

@Resource
	private ProductRepository productRepository;

二.一 新增文档

/**
	 * 新增文档操作
	 */
	@Test
	public void addTest() {
		Product product = new Product();
		product.setId(1);
		product.setTitle("两个蝴蝶飞学习 ES");
		product.setCategory("图书");
		product.setPrice(40.0d);
		product.setImage("https://www.yueshushu.top");
		productRepository.save(product);
		log.info(">>> 创建生成单个文档成功");
	}

SpringBoot 整合 ES (六)_spring_02

二.二 根据 id 查询文档

/**
	 * 根据id 查询文档
	 */
	@Test
	public void searchByIdTest() {
		Optional<Product> productOptional = productRepository.findById(1);
		if (productOptional.isPresent()) {
			Product product = productOptional.get();
			log.info(">>> 查询文档信息:{}", product);
		} else {
			log.info(">>> 没有此文档");
		}
	}

2023-04-10 13:42:03.870  INFO 41120 --- [           main] top.yueshushu.DocumentTest               : >>> 查询文档信息:Product(id=1, title=两个蝴蝶飞学习 ES, author=null, category=图书, price=40.0, image=https://www.yueshushu.top)

二.三 根据文档

/**
	 * 更新文档
	 */
	@Test
	public void updateByIdTest() {
		// 更新文档
		Optional<Product> productOptional = productRepository.findById(1);
		if (!productOptional.isPresent()) {
			return;
		}
		Product product = productOptional.get();
		product.setPrice(38.0d);
		product.setCategory("Java");
		
		//进行更新
		productRepository.save(product);
		
		log.info(">>> 更新文档成功");
	}

SpringBoot 整合 ES (六)_elasticsearch_03

二.四 根据 id 删除文档

/**
	 * 根据id 删除文档
	 */
	@Test
	public void deleteByIdTest() {
		productRepository.deleteById(1);
		log.info(">>> 删除文档成功");
		searchByIdTest();
	}

执行后,文档会删除。

二.五 批量添加文档

/**
	 * 批量添加文档
	 */
	@Test
	public void batchInsertTest() {
		List<Product> list = new ArrayList<>();
		for (int i = 0; i <= 10; i++) {
			Product product = new Product();
			product.setId(i + 1);
			product.setTitle("两个蝴蝶飞学习 ES" + i);
			product.setCategory("图书");
			product.setPrice(40.0d * i);
			product.setImage("https://www.yueshushu.top");
			list.add(product);
		}
		//批量添加
		productRepository.saveAll(list);
		log.info(">>>批量添加文档成功");
	}

SpringBoot 整合 ES (六)_elasticsearch_04

二.六 全部查询文档

/**
	 * 批量查询文档
	 */
	@Test
	public void findAllTest() {
		Iterable<Product> allList = productRepository.findAll();
		allList.forEach(
				n -> log.info("文档:{}", n)
		);
	}

SpringBoot 整合 ES (六)_elasticsearch_05

二.七 根据 id 批量查询记录

/**
	 * 根据id 集合批量查询记录
	 */
	@Test
	public void findAllByIdListTest() {
		Iterable<Product> allList = productRepository.findAllById(Arrays.asList(1, 5, 6));
		allList.forEach(
				n -> log.info("文档:{}", n)
		);
	}

SpringBoot 整合 ES (六)_Test_06

二.八 批量更新

/**
	 * 批量更新, id一样,则更新。没有id,则添加。
	 */
	@Test
	public void batchUpdateTest() {
		Iterable<Product> allList = productRepository.findAllById(Arrays.asList(1, 5, 6));
		allList.forEach(
				n -> {
					n.setPrice(10.d);
					n.setImage("http://被修改了");
				}
		);
		List<Product> list = new ArrayList<>();
		for (int i = 20; i <= 22; i++) {
			Product product = new Product();
			product.setId(i + 1);
			product.setTitle("两个蝴蝶飞学习 Java " + i);
			product.setCategory("图书");
			product.setPrice(40.0d * i);
			product.setImage("http://url1");
			list.add(product);
		}
		ArrayList<Product> findALlList = Lists.newArrayList(allList);
		list.addAll(findALlList);
		
		//批量处理
		productRepository.saveAll(list);
		
		log.info(">>>>批量修改成功");
		findAllTest();
	}

SpringBoot 整合 ES (六)_spring_07

二.九 批量删除

/**
	 * 批量删除
	 */
	@Test
	public void batchDeleteTest() {
		Iterable<Product> allList = productRepository.findAllById(Arrays.asList(1, 2, 3));
		ArrayList<Product> findALlList = Lists.newArrayList(allList);
		productRepository.deleteAll(findALlList);
		log.info(">>>> 批量删除成功");
		findAllTest();
	}

再次查询时,会查询不到 id为 1,2,3 的记录信息

三. 查询

除了全部查询, 或者 根据id 查询, 一般会使用 ElasticsearchRestTemplate 进行查询

@Resource
	private ElasticsearchRestTemplate elasticsearchRestTemplate;

三.一 全部查询

/**
	 * 全部查询
	 */
	@Test
	public void findAllTest() {
		NativeSearchQuery nativeSearchQuery =
				new NativeSearchQuery(QueryBuilders.matchAllQuery());
		
		SearchHits<Product> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		showInfo(searchHits);
	}

	/**
	 * 展示信息
	 */
	public void showInfo(SearchHits<Product> searchResult) {
		long totalHits = searchResult.getTotalHits();
		log.info(">>> 总数:{}", totalHits);
		List<SearchHit<Product>> searchHitList = searchResult.getSearchHits();
		searchHitList.forEach(
				n -> {
					Product product = n.getContent();
					log.info(">>> 输出信息:{}", product);
					if (!CollectionUtils.isEmpty(n.getHighlightFields())){
						log.info("高亮:{}", n.getHighlightFields());
					}
				}
		);
	}

SpringBoot 整合 ES (六)_Test_08

三.二 根据id 查询

/**
	 * 一个简单的查询
	 * id =4
	 */
	@Test
	public void simpleQueryTest() {
		NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(
				QueryBuilders.termQuery("id", "4"));
		SearchHits<Product> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		showInfo(searchHits);
	}

SpringBoot 整合 ES (六)_Test_09

三.三 分页查询

/**
	 * 分页查询
	 * 从 0开始
	 */
	@Test
	public void pageTest() {
		NativeSearchQuery nativeSearchQuery =
				new NativeSearchQuery(QueryBuilders.matchAllQuery());
		Pageable pageable = PageRequest.of(2, 4);
		nativeSearchQuery.setPageable(pageable);
		
		// 进行查询
		SearchHits<Product> search = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		showInfo(search);
		
	}

SpringBoot 整合 ES (六)_elasticsearch_10

三.四 分页排序查询

/**
	 * 分页排序
	 */
	@Test
	public void sortTest() {
		NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(
				QueryBuilders.matchAllQuery()
		);
		Sort sort = Sort.by(Sort.Order.desc("price"));
		Pageable pageable = PageRequest.of(1, 4, sort);
		nativeSearchQuery.setPageable(pageable);
		
		SearchHits<Product> search = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		showInfo(search);
	}

SpringBoot 整合 ES (六)_elasticsearch_11

三.五 bool 查询

/**
	 * bool 查询, 类型必须是图片, id不能为5.
	 * name 可以为
	 */
	@Test
	public void boolTest() {
		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
		boolQueryBuilder.must(QueryBuilders.termQuery("category", "图书"));
		boolQueryBuilder.mustNot(QueryBuilders.termQuery("id", 5));
		boolQueryBuilder.should(QueryBuilders.termQuery("price", 360.0d));
		NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);
		SearchHits<Product> search = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		showInfo(search);
	}

SpringBoot 整合 ES (六)_Test_12

三.六 range 范围查询

@Test
	public void rangeTest() {
		RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
		rangeQueryBuilder.gte(100.0);
		rangeQueryBuilder.lte(300.0d);
		
		NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(rangeQueryBuilder);
		
		SearchHits<Product> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		showInfo(searchHits);
	}

SpringBoot 整合 ES (六)_elasticsearch_13

三.七 like 查询

@Test
	public void likeTest() {
		FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("title", "学哈");
		fuzzyQueryBuilder.fuzziness(Fuzziness.ONE);
		
		NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(fuzzyQueryBuilder);
		
		SearchHits<Product> search = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		showInfo(search);
	}

故意将 学习 变成 学哈

SpringBoot 整合 ES (六)_spring_14

三.八 高亮展示

@Test
	public void hightTest() {
		HighlightBuilder highlightBuilder = new HighlightBuilder();
		highlightBuilder.preTags("<font color='red'>");
		highlightBuilder.postTags("</font>");
		highlightBuilder.field("title");
		
		FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("title", "学哈");
		fuzzyQueryBuilder.fuzziness(Fuzziness.ONE);
		NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(fuzzyQueryBuilder, null, null, highlightBuilder, null);
		
		SearchHits<Product> search = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		showInfo(search);
		
	}

SpringBoot 整合 ES (六)_elasticsearch_15

三.九 组合条件查询

@Test
	public void criteriaTest() {
		// 条件查询
		Criteria criteria = Criteria.where(new SimpleField("title")).contains("学习")
            .or( new SimpleField("id")).greaterThan("5");
		CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
		SearchHits<Product> search = elasticsearchRestTemplate.search(criteriaQuery, Product.class);
		showInfo(search);
	}

SpringBoot 整合 ES (六)_spring_16

本章节的代码放置在 github 上:

https://github.com/yuejianli/springboot/tree/develop/SpringBoot_ES2

谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!


举报

相关推荐

0 条评论