es+springboot实现简单的数据增删改查,全字段检索功能_es全字段查询_玉之之
需求:实现在对数据库查询时,同时更新ES服务中指定索引的数据。若用户重建数据库,则需删除旧索引,查询数据库新数据,而后插入指定新索引中。...
意愿:完成在对数计算据库查到时,也的更新ES服务管理大拇选定指数的资料。若客户从建资料库,则需移除旧指数,查到资料库新资料,其后进到这一领域选定新指数中。 創建字段开始之前,去大统计数据报告方法方法位置(方法方法大统计数据报告操作过程中并且更新换代如今字段大统计数据报告):
点再建指数快捷过后,来进行常用对数据检索式部门:第一步,首先了解,安装Elasticsearch,注意各个版本的对应,否则会运行失败
elasticsearch:7.16.3 spring-boot-starter-parent:2.3.0.RELEASE 当运转之前插入//localhost:9200/ 假设有折回值则就说明使用非常成功第二步,引用ES(这里运用的RestHighLevelClient中封装好的方法)
<!--全文检索-->
<!--添加springboot-elasticsearch依赖-->
<!--es客户端,不使用springboot封装的客户端-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.5.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.6.2</version>
</dependency>
application.yml中的配置如下:
?
elasticsearch:
schema: http
address: 127.0.0.1:9200
connectTimeout: 5000
socketTimeout: 5000
connectionRequestTimeout: 5000
maxConnectNum: 100
maxConnectPerRoute: 100
免费阅读查找包块后端开发模块结构类型:
?
?其中config配置类如下(必须使用)
/**
* @Deacription ElasticSearch 配置
* @Author hmf
* @Date 2022/8/29
* @Version 1.0
**/
@Configuration
public class ElasticSearchConfiguration {
/** 协议 */
@Value("${elasticsearch.schema:http}")
private String schema;
/** 集群地址,如果有多个用“,”隔开 */
@Value("${elasticsearch.address}")
private String address;
/** 连接超时时间 */
@Value("${elasticsearch.connectTimeout}")
private int connectTimeout;
/** Socket 连接超时时间 */
@Value("${elasticsearch.socketTimeout}")
private int socketTimeout;
/** 获取连接的超时时间 */
@Value("${elasticsearch.connectionRequestTimeout}")
private int connectionRequestTimeout;
/** 最大连接数 */
@Value("${elasticsearch.maxConnectNum}")
private int maxConnectNum;
/** 最大路由连接数 */
@Value("${elasticsearch.maxConnectPerRoute}")
private int maxConnectPerRoute;
@Bean(name = "restHighLevelClient")
public RestHighLevelClient restHighLevelClient() {
// 拆分地址
List<HttpHost> hostLists = new ArrayList<>();
String[] hostList = address.split(",");
for (String addr : hostList) {
String host = addr.split(":")[0];
String port = addr.split(":")[1];
hostLists.add(new HttpHost(host, Integer.parseInt(port), schema));
}
// 转换成 HttpHost 数组
HttpHost[] httpHost = hostLists.toArray(new HttpHost[]{});
// 构建连接对象
RestClientBuilder builder = RestClient.builder(httpHost);
// 异步连接延时配置
builder.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(connectTimeout);
requestConfigBuilder.setSocketTimeout(socketTimeout);
requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeout);
return requestConfigBuilder;
});
// 异步连接数配置
builder.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(maxConnectNum);
httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
return httpClientBuilder;
});
return new RestHighLevelClient(builder);
}
}
?ENTITY中的实体类(返回前端,存入ES的数据格式)
其中Document必须提前设置好指定存入的index(可以理解成数据库的某个表)?
/**
* @author hmf
* @create 2022-08-29 10:28
*/
@Data
@Document(indexName = "gt_office_doc", type = "_doc")
public class OfficeDocVO {
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String officeDocFileId;
@JSONField(serialize = false)
private MultipartFile docFileContent;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String docFileName;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String docFileKeyword;
@Id
private String officeDocId;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String docTitle;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String dispatchnoId;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String issuingAuthority;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String issuingAuthorityYear;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String postingSequenceNumber;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String orgUuid;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String orgName;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String drafterId;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String drafterName;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String uploaderName;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date draftDate;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date uploadTime;
@Field(type = FieldType.Text, searchAnalyzer = "ik_smart", analyzer = "ik_max_word")
private String previewUrl;
}
?Serivce中封装的主要方法(增删改查)
OFFICE_INDEX为设置好的全局常量,内容为:gt_office_doc (也就是index)
其中,初始化数据时候,是从数据库中查询LIST而后插入ES(批量操作)
@Async为异步请求,考虑当数据库中的数据较多,反应时间较长,加载批量操作数据的方法中
其中,全字段检索使用了multiMatchQuery,将需要匹配的字段写入,则可按照查询。
import static com.icss.audit.gt.constant.CommonConst.OFFICE_INDEX;
/**
* @author hmf
* @create 2022-08-29
*/
@Slf4j
@Service
public class EsIndexService {
@Resource
ElasticsearchRestTemplate elasticsearchRestTemplate;
@Autowired
private RestHighLevelClient restHighLevelClient;
@Resource
OfficeDocumentDao officeDocumentDao;
/**
* 创建索引
*/
public void createIndex() throws Exception {
if (elasticsearchRestTemplate.indexOps(IndexCoordinates.of(OFFICE_INDEX)).exists()){
deleteIndex();
}
// 创建索引配置信息,配置
Settings settings = Settings.builder()
.put("index.number_of_shards", 1)
.put("index.number_of_replicas", 0)
.build();
// 新建创建索引请求对象,然后设置索引类型(ES 7.0 将不存在索引类型)和 mapping 与 index 配置
CreateIndexRequest request = new CreateIndexRequest(OFFICE_INDEX, settings);
// RestHighLevelClient 执行创建索引
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
// 判断是否创建成功
boolean isCreated = createIndexResponse.isAcknowledged();
if (isCreated){
//初始化数据
initEsData();
}
}
/**
* 删除索引
*/
public void deleteIndex()throws Exception {
// 新建删除索引请求对象
DeleteIndexRequest request = new DeleteIndexRequest(OFFICE_INDEX);
// 执行删除索引
AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
// 判断是否删除成功
log.info("索引是否删除成功:" + acknowledgedResponse.isAcknowledged());
}
/**
* 初始化索引数据
*/
@Async
public void initEsData() throws Exception{
List<OfficeDocVO> resultlist = officeDocumentDao.initIndexData();
//增加预览参数
for(OfficeDocVO temp : resultlist){
if (temp.getDocFileName().endsWith(".pdf")){
temp.setPreviewUrl("/officeDocument/PreviewOfficeDoc?id=");
}
}
// 创建索引请求对象
BulkRequest bulkRequest = new BulkRequest();
// 准备批量插入的数据
resultlist.forEach(user -> {
// 设置请求对象
IndexRequest request = new IndexRequest(OFFICE_INDEX);
// 文档id
request.id(user.getOfficeDocId());
// 将json格式字符串放在请求中
// 下面这种写法也可以写成:request.source(XContentType.JSON, "name", "张三", "age", "男", "age", 22);,其中"name"、"age"、 "age"是User对象中的字段名,而这些字段名称后面的值就是对应的值
System.out.println("插入的数据为:"+user.toString());
request.source(JSONObject.toJSONString(user), XContentType.JSON);
// 将request添加到批量处理请求中
bulkRequest.add(request);
});
// 3、发送请求到ES
BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
// 4、处理响应结果
log.info("批量插入是否失败:" + response.hasFailures());
}
/**
* 获取所有文档信息
*/
public SearchResponse getDocument(PageData page) throws IOException {
// 获取请求对象
SearchRequest getRequest = new SearchRequest(OFFICE_INDEX, "", "");
// 指定检索条件
SearchSourceBuilder builder = new SearchSourceBuilder();
Map<String, Object> condition = page.getCondition();
String AuthorityYear = "";
String Authority = "";
String ownerUnit = "";
int currentPage = (int) page.getCurrent();
int pageSize = 10;
int from = (currentPage - 1) * pageSize;
builder.from(from);
builder.size(pageSize);
// 若无参则用来查询索引中全部的数据
builder.query(QueryBuilders.matchAllQuery());
getRequest.source(builder);
if (condition != null) {
if (condition.get("AuthorityYear") != "") {
AuthorityYear = (String) condition.get("AuthorityYear");
builder.query(QueryBuilders.termQuery("issuingAuthorityYear.keyword", AuthorityYear));
getRequest.source(builder);
}
if (condition.get("Authority") != "") {
Authority = condition.get("Authority").toString();
builder.query(QueryBuilders.termQuery("dispatchnoId.keyword", Authority));
getRequest.source(builder);
}
/*全文检索*/
if (condition.get("ownerUnit") != ""){
ownerUnit = condition.get("ownerUnit").toString();
//多个字段条件匹配查询(multiMatchQuery)
builder.query(QueryBuilders.multiMatchQuery(ownerUnit,"docTitle","issuingAuthority","issuingAuthorityYear","postingSequenceNumber","orgName","drafterName","uploaderName"));
getRequest.source(builder);
}
}
// 3、发送请求到ES
return restHighLevelClient.search(getRequest, RequestOptions.DEFAULT);
// // 4、处理响应结果
// for (SearchHit hit : response.getHits().getHits()) {
// OfficeDocVO officeInfo = JSON.parseObject(hit.getSourceAsString(), OfficeDocVO.class);
// log.info("所有信息:{}", officeInfo);
// }
}
/**
* 新增索引数据
*/
public void addEsDoc(OfficeDocVO officeDocVO)throws IOException{
// 定义请求对象
IndexRequest request = new IndexRequest(OFFICE_INDEX);
// 设置文档id
request.id(officeDocVO.getOfficeDocId());
// 将json格式字符串放在请求中
request.source(JSONObject.toJSONString(officeDocVO), XContentType.JSON);
// 3、发送请求到ES
IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
}
/**
* 更新索引数据
*/
public void updateEsDoc(OfficeDocVO officeDocVO)throws IOException{
UpdateRequest request = new UpdateRequest();
request.index(OFFICE_INDEX).id(officeDocVO.getOfficeDocId());
// 拓展:局部更新也可以这样写:request.doc(XContentType.JSON, "name", "李四", "age", 25);,其中"name"和"age"是User对象中的字段名称,而"小美"和20是对应的字段值
request.doc(JSONObject.toJSONString(officeDocVO), XContentType.JSON);
// 3、发送请求到ES
UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
}
/**
* 删除索引数据
* @param OfficeDocId
* @throws Exception
*/
public void deleteEsDoc(String OfficeDocId)throws Exception{
// 2、定义请求对象
DeleteRequest request = new DeleteRequest(OFFICE_INDEX);
request.id(OfficeDocId);
// 3、发送请求到ES
DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
}
}
EsSearchContoller
/**
* @author hmf
* @create 2022-08-26 10:44
*/
@Api(tags = "ES全文检索")
@RestController
@CrossOrigin
@RequestMapping("/EsSearch")
public class EsSearchContoller {
@Resource
RestHighLevelClient client;
@Resource
EsIndexService esIndexService;
@ApiOperation("初始化ES数据以及index")
@RequestMapping("/initIndex")
public void createIndex()throws Exception{
esIndexService.createIndex();
}
@ApiOperation("ES数据查询以及全文检索")
@RequestMapping("/getEsData")
public SearchResponse getEsData(@RequestBody PageData page)throws IOException{
return esIndexService.getDocument(page);
}
}
第三步,前端获取数据?
还要还要注意从ES在线查询下来的请收藏本站值内存在res.hits.hits中 主要是因为高速传输中,将大数据源显示库里的大数据源显示日期种类存入ES之后转成日期戳,加载前段后动态展示大数据源显示会变身日期戳。 在web后台加注解也是策略中的一个, 但那里是用前边实施转为。 // 表格初始化
Initialization(data){
let condition = {
AuthorityYear:data.parentid,
Authority:data.dispatchnoId,
ownerUnit:this.formInline.ownerUnit,
};
let size = this.page.size;
let current=this.page.currentPage;
let Params = {condition,size,current}
this.request('/EsSearch/getEsData',Params,'post').then((res) =>{
if (res.hits.hits.length > 0){
res.hits.hits.forEach(element => {
element.sourceAsMap.draftDate = this.Time(element.sourceAsMap.draftDate);
element.sourceAsMap.uploadTime = this.Time(element.sourceAsMap.uploadTime);
});
this.tableData = res.hits.hits;
}else{
//表格重置为空
this.tableData=[];
}
//重置显示总数
this.page.total=res.hits.totalHits.value;
})
},
Time(time) { //处理时间
// return moment(parseInt(e)).format('YYYY-MM-DD');
//将13位时间戳转换成时间格式 输出为2018-10-09
let date = new Date(time);
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
var myDate = ''
myDate = year + '-' + month + '-' + day;
return myDate
},
?
皇冠新体育APP相关的文章
- 皇冠新体育APP:兔老大的系统设计(一)健康度系统_兔老大RabbitMQ_redis 健康度
- 皇冠新体育APP:NoSQL的概念以及Redis的安装_不入开发不工作
- 皇冠新体育APP:基于Springboot+vue的疫情防控管理系统_辰兮要努力
- 皇冠新体育APP:NoSQL数据库Redis_正大光明瑞士卷
- 皇冠新体育APP:Tomcat安装与配置教程(图文教学)_FlagHilling_tomcat高级教程
- 数据库理论_碳苯
- 【Rust指南】组织管理|路径表示|访问权限_微凉秋意
- Redis??基于尚硅谷Redis课程_利明的秃头之旅_尚硅谷redis
- 皇冠新体育APP:Windows 安装MySQL 8.0 超详细教程(mysql 8.0.30)_程序前行者
- Oracle12C日志出现error=904怎样解决_yangqi000_oracle错误904解决方法
- 【MongoDB】 1.入门 《MongoDB权威指南》【七天读书】_小雨青年_mongodb权威指南
- springboot整合RabbitMQ 中的 TTL_笑霸final
- 高并发高可用之MongoDB_Traving Yu_mongodb 高并发写
- 数据库-MySQL-索引介绍_莫浅子
- 分布式数据库NoSQL(五)??MongoDB 之滴滴、摩拜都在用的索引_坞吾5雾_mongodb数据库勒索
- 皇冠新体育APP:猿创征文|Spring Boot日志_Binaire-沐辰