主机托管网站,网络营销的未来发展趋势论文,如何做一个电商,网站建设公司营业执照经营范围Elasticsearch#xff1a;一个分布式的、Restful 风格的搜索引擎#xff1b;支持对各种类型的数据的索引#xff1b;搜索速度快#xff0c;可以提供实时的搜索服务#xff1b;便于水平扩展#xff0c;每秒可以处理 PB 级海量数据 目录
1.Spring 整合 Elasticsearch
1.1…Elasticsearch一个分布式的、Restful 风格的搜索引擎支持对各种类型的数据的索引搜索速度快可以提供实时的搜索服务便于水平扩展每秒可以处理 PB 级海量数据 目录
1.Spring 整合 Elasticsearch
1.1 实体类与 ES 建立关系
1.2 实现接口
1.3 测试类 1.Spring 整合 Elasticsearch
引入依赖spring-boot-starter-data-elasticsearch配置 Elasticsearchcluster-name、cluster-notesSpring Data ElaticsearchElaticsearchRestTemplate、ElaticsearchRepository
依赖
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-elasticsearch/artifactId
/dependency
配置
# ElasticsearchProperties
spring.data.elasticsearch.cluster-namexiaowen
spring.data.elasticsearch.cluster-nodes127.0.0.1:9300 解决冲突Elasticsearch 底层是基于 NettyRedis 底层也是基于 Netty两者启动 natty 的时候由冲突
在 Application 类核心入口配置类最先被加载的添加
添加 PostConstruct 注解管理 Bean 的初始化方法由注解所修饰的方法会在构造器调用完成之后被执行添加方法解决 netty 启动冲突问题Netty4Utils.setAvailableProcessors()
package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;import javax.annotation.PostConstruct;SpringBootApplication
public class DemoApplication {//添加 PostConstruct 注解管理 Bean 的初始化方法由注解所修饰的方法会在构造器调用完成之后被执行PostConstructpublic void init() {// 解决netty启动冲突问题// see Netty4Utils.setAvailableProcessors()System.setProperty(es.set.netty.runtime.available.processors, false);}public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}} 1.1 实体类与 ES 建立关系
编写与需求相关的代码把数据库中存的帖子再存到 ES 服务器中在 ES 服务器中搜索帖子
帖子表存到 ES 中的索引每个字段对应的类型、怎么搜索都是要进行配置但是配置不需要写 xml 文件通过注解实现注解写在实体类中针对帖子操作写在 discussPost 类中
在此类中添加注解 Document(indexName , type , shards , replicas )Spring 整合 ES底层访问 ES 会自动将实体数据和 ES 服务器的索引映射indexName索引type类型shards分片replicas副本ElasticSearch7.x已经不推荐使用type了并且将在8.0彻底移除主键通常会加 Id、普通字段添加 Field(type FiledType. )重点是 title 和 context搜索帖子主要搜索标题和内容类型为 type FieldType.Text存储的时候尽可能多的拆分关键词增加搜索范围使用 analyzer ik_max_word搜索的时候需要尽可能满足需求不需要拆分太多次使用searchAnalyzer ik_smart
/*** 与 ES 中的索引对应*///Spring 整合 ES底层访问 ES 会自动将实体数据和 ES 服务器的索引映射
Document(indexName discusspost)
public class DiscussPost {Idprivate int id;Field(type FieldType.Integer)private int userId;//搜索帖子主要搜索标题和内容//存储的时候尽可能多的拆分关键词增加搜索范围使用 analyzer ik_max_word// 搜索的时候需要尽可能满足需求不需要拆分太多次使用searchAnalyzer ik_smartField(type FieldType.Text, analyzer ik_max_word, searchAnalyzer ik_smart)private String title;Field(type FieldType.Text, analyzer ik_max_word, searchAnalyzer ik_smart)private String content;Field(type FieldType.Integer)private int type;Field(type FieldType.Integer)private int status;//帖子状态Field(type FieldType.Date)private Date createTime;//创建时间Field(type FieldType.Integer)private int commentCount;//评论数量Field(type FieldType.Double)private double score;//分数
}
上述这个实体类就和es之间的数据建立了联系。
1.2 实现接口
在dao下新建elasticsearch实现 DiscussPostRepository 接口继承时声明泛型主键类型
添加注解 Repository这个接口是数据访问层代码ES可以看作特殊的数据库Mapper 是 MyBatis 专用注解
package com.example.demo.dao.elasticsearch;import com.example.demo.entity.DiscussPost;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;Repository
public interface DiscussPostRepository extends ElasticsearchRepositoryDiscussPost, Integer {}
1.3 测试类
package com.example.demo;import com.example.demo.dao.DiscussPostMapper;
import com.example.demo.dao.elasticsearch.DiscussPostRepository;
import com.example.demo.entity.DiscussPost;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
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.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
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.SpringRunner;import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;RunWith(SpringRunner.class)
SpringBootTest
ContextConfiguration(classes DemoApplication.class)
public class ElasticsearchTests {Autowiredprivate DiscussPostMapper discussMapper;Autowiredprivate DiscussPostRepository discussRepository;Autowiredprivate ElasticsearchRestTemplate elasticsearchRestTemplate;//查询Testpublic void testInsert() {discussRepository.save(discussMapper.selectDiscussPostById(241));discussRepository.save(discussMapper.selectDiscussPostById(242));discussRepository.save(discussMapper.selectDiscussPostById(243));}//插入多条数据Testpublic void testInsertList() {discussRepository.saveAll(discussMapper.selectDiscussPosts(101, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(102, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(103, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(111, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(112, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(131, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(132, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(133, 0, 100));discussRepository.saveAll(discussMapper.selectDiscussPosts(134, 0, 100));}//修改Testpublic void testUpdate() {DiscussPost post discussMapper.selectDiscussPostById(231);post.setContent(我是新人,使劲灌水.);discussRepository.save(post);}//删除Testpublic void testDelete() {// discussRepository.deleteById(231);discussRepository.deleteAll();}//搜索Testpublic void testSearchByRepository() {NativeSearchQuery searchQuery new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery(互联网寒冬, title, content)).withSorts(SortBuilders.fieldSort(type).order(SortOrder.DESC),SortBuilders.fieldSort(score).order(SortOrder.DESC),SortBuilders.fieldSort(createTime).order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).withHighlightFields( //高亮显示new HighlightBuilder.Field(title).preTags(em).postTags(/em),new HighlightBuilder.Field(content).preTags(em).postTags(/em)).build();// elasticTemplate.queryForPage(searchQuery, class, SearchResultMapper)// 底层获取得到了高亮显示的值, 但是没有返回.IterableDiscussPost page discussRepository.findAll();for (DiscussPost post : page) {System.out.println(post);}}// 查询数据并将关键字高亮显示Testpublic void testSearchByTemplate() {// withQuery()用于构造搜索条件NativeSearchQuery searchQuery new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery(互联网寒冬, title, content)).withSorts(SortBuilders.fieldSort(type).order(SortOrder.DESC),SortBuilders.fieldSort(score).order(SortOrder.DESC),SortBuilders.fieldSort(createTime).order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).withHighlightFields(new HighlightBuilder.Field(title).preTags(em).postTags(/em),new HighlightBuilder.Field(content).preTags(em).postTags(/em)).build();//查询SearchHitsDiscussPost search elasticsearchRestTemplate.search(searchQuery, DiscussPost.class);long count elasticsearchRestTemplate.count(searchQuery, DiscussPost.class);System.out.println(共查询到: count 条数据);//得到查询返回的内容ListSearchHitDiscussPost searchHits search.getSearchHits();// 设置一个最后需要返回的实体类集合ListDiscussPost discussPosts new ArrayList();// 遍历返回的内容进行处理for (SearchHitDiscussPost hit : searchHits) {// 获取高亮的内容MapString, ListString highlightFields hit.getHighlightFields();// 将高亮的内容添加到content中(匹配到的如果是多段就将第一段高亮显示)// 没有匹配到关键字就显示原来的title和contenthit.getContent().setTitle(highlightFields.get(title)null ? hit.getContent().getTitle():highlightFields.get(title).get(0));hit.getContent().setContent(highlightFields.get(content)null ? hit.getContent().getContent():highlightFields.get(content).get(0));// 放到实体类中discussPosts.add(hit.getContent());}for (DiscussPost post : discussPosts) {System.out.println(post);}}
}