package cn.cslg.pas.service.business.es; import cn.cslg.pas.common.core.base.IfConstant; import cn.cslg.pas.common.dto.PatentColumnDTO; import cn.cslg.pas.common.dto.PatentDTO; import cn.cslg.pas.common.dto.PatentDetailDTO; import cn.cslg.pas.common.dto.PatentKinDTO; import cn.cslg.pas.common.dto.business.ContentDetailDTO; import cn.cslg.pas.common.model.cronModel.Records; import cn.cslg.pas.common.model.request.MapRequest; import cn.cslg.pas.common.model.request.OrderDTO; import cn.cslg.pas.common.model.request.QueryRequest; import cn.cslg.pas.common.model.request.StringRequest; import cn.cslg.pas.common.utils.parseQueryToTree.expressManager; import cn.cslg.pas.common.utils.parseQueryToTree.operateNode; import cn.cslg.pas.common.utils.parseQueryToTree.treeNode; import cn.cslg.pas.common.vo.ContentVO; import cn.cslg.pas.common.vo.EsConfigVO; import cn.cslg.pas.common.vo.PatentPageMessageVO; import cn.cslg.pas.common.vo.PatentWithIdVO; import cn.cslg.pas.common.vo.business.PatentKinDetailVO; import cn.cslg.pas.common.vo.business.PatentKinVO; import cn.cslg.pas.common.vo.business.PatentNoVO; import cn.cslg.pas.domain.es.*; import cn.cslg.pas.service.business.CommonService; import cn.cslg.pas.service.query.FormatQueryService; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.SortOrder; import co.elastic.clients.elasticsearch._types.query_dsl.Query; import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders; import co.elastic.clients.elasticsearch.core.SearchRequest; import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.elasticsearch.core.search.SourceConfig; import co.elastic.clients.elasticsearch.core.search.SourceConfigBuilders; import co.elastic.clients.elasticsearch.transform.Source; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSONObject; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Service @RequiredArgsConstructor(onConstructor_ = {@Lazy}) public class EsPatentService { private final ElasticsearchClient client; private final FormatQueryService formatQueryService; /** * 根据专利号查询专利详情 * * @param vo * @return * @throws IOException */ public PatentDetailDTO selectPatentDetail(PatentNoVO vo) throws IOException { PatentDetailDTO dto = new PatentDetailDTO(); SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); Query q = QueryBuilders.term(i -> i.field("patent_no.keyword").value(vo.getPatentNo())); Query query = QueryBuilders.bool(i -> i.must(q)); builder.query(query); SearchResponse response = client.search(builder.build(), Patent.class); List> hits = response.hits().hits(); for (Hit hit : hits) { Patent esMess = hit.source(); BeanUtils.copyProperties(esMess, dto); dto.setMC(esMess.getMipc()); dto.setLG(esMess.getLegalStatus()); dto.setSS(esMess.getSimpleStatus()); dto.setPT(esMess.getPatentType()); if (!CollectionUtils.isEmpty(esMess.getTitle())) { dto.setTitle(this.loadContent(esMess.getTitle())); } if (!CollectionUtils.isEmpty(esMess.getAbstractStr())) { dto.setAbstractStr(this.loadContent(esMess.getAbstractStr())); } if (!CollectionUtils.isEmpty(esMess.getClaim())) { dto.setClaim(this.loadContent(esMess.getClaim())); } if (!CollectionUtils.isEmpty(esMess.getApplicant())) { dto.setApplicant(this.loadName(esMess.getApplicant())); } if (!CollectionUtils.isEmpty(esMess.getRightHolder())) { dto.setRightHolder(this.loadName(esMess.getRightHolder())); } if (!CollectionUtils.isEmpty(esMess.getInventor())) { dto.setInventor(this.loadName(esMess.getInventor())); } } return dto; } //通用返回摘要、标题、权利要求具体内容 public ContentVO loadContent(List list) { ContentVO contentVO = new ContentVO(); String content = StringUtils.strip(JSON.toJSONString(list), "[]"); ContentDetailDTO contentDetailDTO = JSONObject.parseObject(content, ContentDetailDTO.class); contentVO.setContent(contentDetailDTO.getTextContent()); return contentVO; } //通用返回申请人、权利人、发明人 public List loadName(List list) { return list.stream().map(PatentPerson::getName).collect(Collectors.toList()); } /** * 根据专利号查询出同族专利列表 * * @param vo * @return * @throws IOException */ public List selectKinByPatentNo(PatentKinVO vo) throws IOException { //1.根据专利号查询出同族 String no = vo.getPatentNo(); Integer pageNum = vo.getPageNum(); Integer pageSize = vo.getPageSize(); String type = vo.getType(); SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent_family"); //申请号 Query q1 = QueryBuilders.term(t -> t.field("app_no.keyword").value(no)); //公开号 Query q2 = QueryBuilders.term(t -> t.field("public_no.keyword").value(no)); //授权号 Query q3 = QueryBuilders.term(t -> t.field("grant_no.keyword").value(no)); //同族类型 Query q4 = QueryBuilders.term(t -> t.field("family_type").value(type)); Query bool = QueryBuilders.bool(i -> i.must(q4).should(q1, q2, q3)); builder.query(bool); //分页 if (pageNum > 0 && pageSize > 0) { builder.from((pageNum - 1) * pageSize).size(pageSize); } SearchResponse response = client.search(builder.build(), PatentFamilyMessage.class); List> hits = response.hits().hits(); List kinDTOS = new ArrayList<>(); for (Hit hit : hits) { PatentFamilyMessage familyMessage = hit.source(); List patentList = familyMessage.getPatent(); if (!CollectionUtils.isEmpty(patentList)) { for (FamilyPatent familyPatent : patentList) { PatentKinDetailVO kinDetailVO = new PatentKinDetailVO(); kinDetailVO.setAppNo(familyPatent.getAppNo()); kinDetailVO.setPublicNo(familyPatent.getPublicNo()); kinDetailVO.setGrantNo(familyPatent.getGrantNo()); PatentKinDTO kinDTO = this.selectPatentKindDetail(kinDetailVO) .stream().findFirst().orElse(null); if (kinDTO != null) { kinDTOS.add(kinDTO); } } } } return kinDTOS; } public List selectPatentKindDetail(PatentKinDetailVO vo) throws IOException { List list = new ArrayList<>(); SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); //申请号 if (StringUtils.isNotEmpty(vo.getAppNo())) { } Query q1 = QueryBuilders.term(t -> t.field("patent_no.keyword").value(vo.getAppNo())); //公开号 Query q2 = QueryBuilders.term(t -> t.field("patent_no.keyword").value(vo.getPublicNo())); //授权号 // Query q3 = QueryBuilders.term(t -> t.field("patent_no.keyword").value(vo.getGrantNo())); Query bool = QueryBuilders.bool(i -> i.should(q1, q2)); builder.query(bool); SearchResponse response = client.search(builder.build(), Patent.class); List> hits = response.hits().hits(); for (Hit hit : hits) { PatentKinDTO kinDTO = new PatentKinDTO(); Patent patent = hit.source(); if (patent != null) { kinDTO.setPatentNo(patent.getPatentNo()); kinDTO.setAppNo(patent.getAppNo()); kinDTO.setPublicNo(patent.getPublicNo()); kinDTO.setGrantNo(patent.getGrantNo()); kinDTO.setTitle(this.loadContent(patent.getTitle())); kinDTO.setAbstractStr(this.loadContent(patent.getAbstractStr())); kinDTO.setApplicant(this.loadName(patent.getApplicant())); kinDTO.setRightHolder(this.loadName(patent.getRightHolder())); list.add(kinDTO); } } return list; } /** * 根据专利号批量查询专利 * * @param patentNos * @return * @throws Exception */ public List getPatentsByNo(List patentNos,Boolean ifGetAll,Long current,Long size) throws Exception { List patentList = new ArrayList<>(); SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); List querys = new ArrayList<>(); for (String patentNo : patentNos) { Query q1 = QueryBuilders.term(t -> t.field("app_no.keyword").value(patentNo)); //公开号 Query q2 = QueryBuilders.term(t -> t.field("public_no.keyword").value(patentNo)); //授权号 Query q3 = QueryBuilders.term(t -> t.field("grant_no.keyword").value(patentNo)); Query query = QueryBuilders.bool(i -> i.should(q1, q2, q3)); querys.add(query); } Query finalQuery = QueryBuilders.bool((i -> i.should(querys))); builder.query(finalQuery); if(!ifGetAll) { List reSources = this.rePatentSource(); builder.source(sourceOptionsBuilder -> sourceOptionsBuilder .filter(fieldSourceBuilder -> fieldSourceBuilder .includes(reSources))); } if (current!=null&&size!=null&¤t > 0 && size > 0) { builder.from((current.intValue() - 1) * size.intValue()).size(size.intValue()); } SearchResponse response = client.search(builder.build(), Patent.class); List> hits = response.hits().hits(); if (hits != null && hits.size() > 0) { hits.forEach(item->{ Patent patent=item.source(); patentList.add(patent);} ); } return patentList; } private List rePatentSource() { List rePatentSource = new ArrayList<>(); rePatentSource.add("patent_no"); rePatentSource.add("app_no"); rePatentSource.add("app_date"); rePatentSource.add("public_no"); rePatentSource.add("public_date"); rePatentSource.add("grant_no"); rePatentSource.add("grant_date"); return rePatentSource; } /** * 检索上一页下一页信息 * * @param queryRequest 检索条件 * @return */ public Records getPatentPageMessage(QueryRequest queryRequest) throws Exception { List patentPageMessageVOS = new ArrayList<>(); Long current = queryRequest.getCurrent(); Long size = queryRequest.getSize(); SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); Query q = this.getQuery(queryRequest); //4. 返回数据 builder.query(q); //排序 List dtoList = queryRequest.getOrderDTOList(); if (!CollectionUtils.isEmpty(dtoList)) { String json = CommonService.readJsonFile("patent.json"); List esConfigVOS = JSON.parseArray(json, EsConfigVO.class); for (OrderDTO orderDTO : dtoList) { EsConfigVO configVO = esConfigVOS.stream().filter(item -> item.getField().equals(orderDTO.getOrderBy())).findFirst().orElse(null); if (configVO != null) { if (orderDTO.getOrderType().equals(IfConstant.NO)) { builder.sort(sortOptionsBuilder -> sortOptionsBuilder .field(fieldSortBuilder -> fieldSortBuilder .field(configVO.getEsField()).order(SortOrder.Asc))); } else { builder.sort(sortOptionsBuilder -> sortOptionsBuilder .field(fieldSortBuilder -> fieldSortBuilder .field(configVO.getEsField()).order(SortOrder.Desc))); } } } } else { builder.sort(sortOptionsBuilder -> sortOptionsBuilder .field(fieldSortBuilder -> fieldSortBuilder .field("patent_no.keyword").order(SortOrder.Desc))); } //分页 if (current > 0 && size > 0) { builder.from(current.intValue()).size(size.intValue()); } SearchResponse response = client.search(builder.build(), Patent.class); List> hits = response.hits().hits(); for (Hit hit : hits) { PatentPageMessageVO patentPageMessageVO = new PatentPageMessageVO(); patentPageMessageVO.setPatentNo(hit.source().getPatentNo()); patentPageMessageVOS.add(patentPageMessageVO); } Records records =new Records(); records.setTotal(response.hits().total().value()); records.setSize(size); records.setCurrent(current); records.setData(patentPageMessageVOS); return records; } /** * 检索上一页下一页信息 * * @param queryRequest 检索条件 * @return */ public List getPatentsWithNotNo(QueryRequest queryRequest, List patentNos) throws Exception { List patentList = new ArrayList<>(); SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); Query q = this.getQuery(queryRequest); Query reQuery =null; if(patentNos!=null&&patentNos.size()>0){ List notInQuery = this.getNoNotInQuery(patentNos); reQuery = QueryBuilders.bool(i -> i.must(q).mustNot(notInQuery)); } else { reQuery = QueryBuilders.bool(i -> i.must(q)); } //4. 返回数据 builder.query(reQuery); List reSources = this.rePatentSource(); builder.source(sourceOptionsBuilder -> sourceOptionsBuilder .filter(fieldSourceBuilder -> fieldSourceBuilder .includes(reSources))); SearchResponse response = client.search(builder.build(), Patent.class); List> hits = response.hits().hits(); for (Hit hit : hits) { if (hits != null && hits.size() > 0) { Patent patent = hit.source(); patentList.add(patent); } } return patentList; } public Long getTotalNum(QueryRequest queryRequest) throws Exception { SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); Query q = this.getQuery(queryRequest); //4. 返回数据 Query reQuery = QueryBuilders.bool(i -> i.must(q)); builder.query(reQuery); List reSources = this.rePatentSource(); builder.source(sourceOptionsBuilder -> sourceOptionsBuilder .filter(fieldSourceBuilder -> fieldSourceBuilder .includes(reSources))); SearchResponse response = client.search(builder.build(), Patent.class); return response.hits().total().value(); } public Query getQuery(QueryRequest queryRequest) throws Exception { String searchCondition = ""; Integer projectId = queryRequest.getProjectId(); //判断表达式 if (queryRequest instanceof StringRequest) { searchCondition = ((StringRequest) queryRequest).getSearchQuery(); } else if (queryRequest instanceof MapRequest) { Map map = ((MapRequest) queryRequest).getSearchQuery(); StringBuilder stringBuilder = new StringBuilder(); for (String key : map.keySet()) { Object value = map.get(key); if (!"".contentEquals(stringBuilder)) { stringBuilder = stringBuilder.append(" AND ").append(key).append("=").append(value); } else { stringBuilder = stringBuilder.append(key).append("=").append(value); } } searchCondition = stringBuilder.toString(); } if (projectId != null) { if (searchCondition != null && !"".equals(searchCondition.trim())) { searchCondition = "projectId = " + projectId + " AND " + searchCondition; } else { searchCondition = "projectId = " + projectId; } } //1. 解析检索条件 treeNode tree = expressManager.getInstance().Parse(searchCondition, false); //格式化检索式 //3. 从es中检索数据 Query q = formatQueryService.EsQueryToQuery((operateNode) tree, "patent"); return q; } private List getNoNotInQuery(List patentNos) { List queryList = new ArrayList<>(); for (String patentNo : patentNos) { Query q1 = QueryBuilders.term(t -> t.field("patent_no.keyword").value(patentNo)); queryList.add(q1); } return queryList; } }