package cn.cslg.pas.service.business; import cn.cslg.pas.common.dto.GetAllCountryDTO; import cn.cslg.pas.common.dto.GetAllPersonDTO; import cn.cslg.pas.common.dto.MergePersonQueryDTO; import cn.cslg.pas.common.dto.PatentColumnDTO; import cn.cslg.pas.common.dto.es.EsMergePersonDTO; import cn.cslg.pas.common.dto.patentCount.GetEsAllPersonDTO; import cn.cslg.pas.common.model.cronModel.PersonnelVO; import cn.cslg.pas.common.model.cronModel.Records; import cn.cslg.pas.common.utils.CacheUtils; import cn.cslg.pas.common.utils.LoginUtils; 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.business.*; import cn.cslg.pas.domain.BaseEntity; import cn.cslg.pas.domain.business.FollowUp; import cn.cslg.pas.domain.business.MergePerson; import cn.cslg.pas.domain.business.SystemDict; import cn.cslg.pas.domain.es.*; import cn.cslg.pas.exception.UnLoginException; import cn.cslg.pas.exception.XiaoShiException; import cn.cslg.pas.mapper.MergePersonMapper; import cn.cslg.pas.mapper.SystemDictMapper; import cn.cslg.pas.service.business.es.EsPatentService; import cn.cslg.pas.service.business.es.EsService; import cn.cslg.pas.service.query.FormatQueryService; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.PageUtil; import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch._types.FieldValue; import co.elastic.clients.elasticsearch._types.InlineScript; import co.elastic.clients.elasticsearch._types.Refresh; import co.elastic.clients.elasticsearch._types.Script; import co.elastic.clients.elasticsearch._types.aggregations.*; import co.elastic.clients.elasticsearch._types.query_dsl.IdsQuery; import co.elastic.clients.elasticsearch._types.query_dsl.Query; import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders; import co.elastic.clients.elasticsearch.core.*; import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.elasticsearch.core.search.TrackHits; import co.elastic.clients.json.JsonData; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.github.pagehelper.PageHelper; import com.google.gson.JsonArray; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.io.IOException; import java.util.*; import java.util.function.BiConsumer; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * @Author xiexiang * @Date 2024/01/02 */ @Slf4j @Service public class MergePersonService extends ServiceImpl { @Autowired private ElasticsearchClient client; @Autowired private CacheUtils cacheUtils; @Autowired private LoginUtils loginUtils; @Autowired private MergePersonMapper mergePersonMapper; @Autowired private FormatQueryService formatQueryService; @Autowired private SystemDictMapper systemDictMapper; /** * 专利列表上新增或编辑发明人/权利人/申请人合并共享接口 * @param commonVO * @return * @throws Exception */ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class) public Integer commonMerge(MergePersonCommonVO commonVO) throws Exception { Integer mergeId = null; if (commonVO.getId() != null) { MergePerson person = mergePersonMapper.selectById(commonVO.getId()); List names = JSON.parseArray(person.getMergedName(), String.class); String delDiffName = ""; if (!commonVO.getName().equals(person.getName())) { names.add(person.getName()); delDiffName = person.getName(); } loadMerging(commonVO, names, person,delDiffName); } else { loadMerging(commonVO, new ArrayList<>(), null, null); } return mergeId; } /** * 封装合并 * @param commonVO * @param names * @param person * @param delDiffName * @return * @throws Exception */ public Integer loadMerging(MergePersonCommonVO commonVO, List names, MergePerson person,String delDiffName) throws Exception { Integer mergeId = null; Integer projectId = commonVO.getProjectId(); Integer type = commonVO.getType(); List mergePersonDTOS = commonVO.getMergePersonDTOS(); List delMergePersonDTOS = commonVO.getDelMergePersonDTOS(); if (!CollectionUtils.isEmpty(mergePersonDTOS)) { List mergeIds = mergePersonDTOS.stream().map(GetAllPersonDTO::getMergeId).filter(Objects::nonNull).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(mergeIds)) { List personList = mergePersonMapper.selectBatchIds(mergeIds); for (MergePerson mergePerson : personList) { List getNames = JSON.parseArray(mergePerson.getMergedName(), String.class); names.addAll(getNames); String personName = mergePerson.getName(); loadNewChild(type, projectId, personName,false); } mergePersonMapper.deleteBatchIds(mergeIds); } List mergeNameList = mergePersonDTOS.stream().filter(i -> i.getMergeId() == null).map(GetAllPersonDTO::getName).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(mergeNameList)) { names.addAll(mergeNameList); } } if (!CollectionUtils.isEmpty(delMergePersonDTOS)) { List delNames = delMergePersonDTOS.stream().map(GetAllPersonDTO::getName).collect(Collectors.toList()); names.removeAll(delNames); loadNewChild(type, projectId, person.getName(),true); } if (commonVO.getId() != null) { mergePersonMapper.deleteById(commonVO.getId()); } if (!CollectionUtils.isEmpty(names)) { List collect = names.stream().distinct().collect(Collectors.toList()); if (!CollectionUtils.isEmpty(collect)) { mergeId = merge(commonVO, collect,delDiffName); } } return mergeId; } /** * 封装子文档 * @param type * @param projectId * @param personName * @param flag * @throws Exception */ private void loadNewChild(Integer type, Integer projectId, String personName,boolean flag) throws Exception { List> hits = searchChild(type, projectId, personName); List patentIds = new ArrayList<>(); List list = new ArrayList<>(); for (Hit hit : hits) { String routing = hit.routing(); patentIds.add(routing); if (flag) { Patent patent = hit.source(); if (type == 0) { if (!CollectionUtils.isEmpty(patent.getMergeApplicant())) { List applicant = patent.getMergeApplicant(); List collect = applicant.stream().filter(i -> i.getIfMerged().equals(Boolean.TRUE)).collect(Collectors.toList()); list.addAll(collect); } if (!CollectionUtils.isEmpty(patent.getMergeRightHolder())) { List rights = patent.getMergeRightHolder(); List collect = rights.stream().filter(i -> i.getIfMerged().equals(Boolean.TRUE)).collect(Collectors.toList()); list.addAll(collect); } } else { if (!CollectionUtils.isEmpty(patent.getMergeInventor())) { List inventors = patent.getMergeInventor(); List collect = inventors.stream().filter(i -> i.getIfMerged().equals(Boolean.TRUE)).collect(Collectors.toList()); list.addAll(collect); } } } } //删除原子文档 deleteChild(patentIds, type, projectId); //查询父文档拿出对应type的数据后添加新的子文档 searchPatent(patentIds, type, projectId); if (flag) { List collect = list.stream().map(PatentMergePerson::getName).distinct().filter(i -> !i.equals(personName)).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(collect)) { for (String key : collect) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper() .eq(MergePerson::getProjectId, projectId) .eq(MergePerson::getName, key) .eq(MergePerson::getType,type); MergePerson mergePerson = mergePersonMapper.selectOne(wrapper); String mergedName = mergePerson.getMergedName(); List mergedNames = JSONArray.parseArray(mergedName, String.class); againMerge(mergedNames,type,projectId,key); } } } } /** * 已存在的合并记录移除名称,不影响另一个合并记录 * @param list * @param type * @param projectId * @param name * @throws Exception */ private void againMerge(List list, Integer type, Integer projectId, String name) throws Exception { List> hits = searchChildDoc(list, type, projectId); //更新合并后的数据 final int num = CollectionUtils.isEmpty(hits) ? 1 : hits.size(); for (Hit hit : hits) { String id = hit.id(); Patent patent = hit.source(); createPatent(patent, type, list, name, num); Integer count = updateChild(patent, id, hit.routing()); if (count < 0) { throw new XiaoShiException("合并失败"); } } } /** * 进行合并 * @param commonVO * @param list * @param delDiffName * @return * @throws Exception */ private Integer merge(MergePersonCommonVO commonVO, List list, String delDiffName) throws Exception { Integer projectId = commonVO.getProjectId(); Integer type = commonVO.getType(); String name = commonVO.getName(); //保存合并记录 Integer mergeId = saveMerge(commonVO, list,delDiffName); //查询合并后的数据 if (StringUtils.isNotEmpty(delDiffName)) { list.add(delDiffName); } List> hits = searchChildDoc(list, type, projectId); //更新合并后的数据 final int num = CollectionUtils.isEmpty(hits) ? 1 : hits.size(); for (Hit hit : hits) { String id = hit.id(); Patent patent = hit.source(); createPatent(patent, type, list, name, num); Integer count = updateChild(patent, id, hit.routing()); if (count < 0) { throw new XiaoShiException("合并失败"); } } return mergeId; } /** * 新增合并记录 * @param vo * @param mergeNames * @param delDiffName * @return */ private Integer saveMerge(MergePersonCommonVO vo, List mergeNames, String delDiffName) { List mergePersonDTOS = vo.getMergePersonDTOS(); List names = new ArrayList<>(); if (!CollectionUtils.isEmpty(mergeNames)) { names = mergeNames; } else { names = mergePersonDTOS.stream().map(GetAllPersonDTO::getName).collect(Collectors.toList()); } if (StringUtils.isNotEmpty(delDiffName)) { names.remove(delDiffName); } //获取登陆人信息 用于设置创建人 PersonnelVO personnelVO = new PersonnelVO(); personnelVO = cacheUtils.getLoginUser(loginUtils.getId()); //判断是否名称重复 LambdaQueryWrapper wrapper = new LambdaQueryWrapper() .eq(MergePerson::getProjectId, vo.getProjectId()) .eq(MergePerson::getType, vo.getType()) .eq(MergePerson::getName, vo.getName()); List list = mergePersonMapper.selectList(wrapper); if (!list.isEmpty()) { throw new XiaoShiException("合并名称不可重复"); } MergePerson person = new MergePerson(); BeanUtils.copyProperties(vo, person); person.setMergedName(JSONArray.toJSONString(names)); person.setCreateId(personnelVO.getId()); person.setCreateTime(new Date()); person.insert(); return person.getId(); } /** * 封装合并人的名称,被合并名称进行替换成合并名称 * @param patent * @param type * @param mergedName * @param name * @param num */ private void createPatent(Patent patent, Integer type, List mergedName, String name, int num) { if (type == 0) { if (!CollectionUtils.isEmpty(patent.getMergeApplicant())) { List mergeApplicant = patent.getMergeApplicant(); for (PatentMergePerson applicant : mergeApplicant) { if (mergedName.contains(applicant.getName().toUpperCase(Locale.ROOT))) { applicant.setName(name); applicant.setIfMerged(true); applicant.setMergedNum(num); } } List applicantList = new ArrayList<>(); Map> map = mergeApplicant.stream().filter(i -> StringUtils.isNotEmpty(i.getName())).collect(Collectors.groupingBy(PatentMergePerson::getName)); for (String key : map.keySet()) { applicantList.add(map.get(key).get(0)); } patent.setMergeApplicant(applicantList); } if (!CollectionUtils.isEmpty(patent.getMergeRightHolder())) { List mergeRightHolder = patent.getMergeRightHolder(); for (PatentMergePerson right : mergeRightHolder) { if (mergedName.contains(right.getName().toUpperCase(Locale.ROOT))) { right.setName(name); right.setIfMerged(true); right.setMergedNum(num); } } List rightList = new ArrayList<>(); Map> map = mergeRightHolder.stream().filter(i -> StringUtils.isNotEmpty(i.getName())).collect(Collectors.groupingBy(PatentMergePerson::getName)); for (String key : map.keySet()) { rightList.add(map.get(key).get(0)); } patent.setMergeRightHolder(rightList); } } else { if (!CollectionUtils.isEmpty(patent.getMergeInventor())) { List mergeInventor = patent.getMergeInventor(); for (PatentMergePerson inventor : mergeInventor) { if (mergedName.contains(inventor.getName().toUpperCase(Locale.ROOT))) { inventor.setName(name); inventor.setIfMerged(true); inventor.setMergedNum(num); } } List inventorList = new ArrayList<>(); Map> map = mergeInventor.stream().filter(i -> StringUtils.isNotEmpty(i.getName())).collect(Collectors.groupingBy(PatentMergePerson::getName)); for (String key : map.keySet()) { inventorList.add(map.get(key).get(0)); } patent.setMergeInventor(inventorList); } } } /** * 根据多个已合并名称查询合并后的数据 * @param mergedNames * @param type * @param projectId * @return * @throws IOException */ private List> searchChildDoc(List mergedNames,Integer type,Integer projectId) throws IOException { SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); List queries = new ArrayList<>(); if (type == 0) { for (String mergedName : mergedNames) { //合并申请人 Query idQ1 = QueryBuilders.term(i -> i.field("merge_applicant.project_id").value(projectId)); Query q1 = QueryBuilders.term(i -> i.field("merge_applicant.name.raw").value(mergedName)); Query bool = QueryBuilders.bool(i -> i.must(idQ1, q1)); Query query1 = QueryBuilders.nested(i -> i.path("merge_applicant").query(bool)); //合并权利人 Query idQ2 = QueryBuilders.term(i -> i.field("merge_right_holder.project_id").value(projectId)); Query q2 = QueryBuilders.term(i -> i.field("merge_right_holder.name.raw").value(mergedName)); Query bool1 = QueryBuilders.bool(i -> i.must(idQ2, q2)); Query query2 = QueryBuilders.nested(i -> i.path("merge_right_holder").query(bool1)); queries.add(query1); queries.add(query2); } } else { for (String mergedName : mergedNames) { Query idQ = QueryBuilders.term(i -> i.field("merge_inventor.project_id").value(projectId)); Query q = QueryBuilders.term(i -> i.field("merge_inventor.name.raw").value(mergedName)); Query bool = QueryBuilders.bool(i -> i.must(idQ, q)); Query query = QueryBuilders.nested(i -> i.path("merge_inventor").query(bool)); queries.add(query); } } Query query = QueryBuilders.bool(i -> i.should(queries)); builder.query(query); builder.size(1000); builder.trackTotalHits(TrackHits.of(i -> i.enabled(true))); SearchResponse response = client.search(builder.build(), Patent.class); return response.hits().hits(); } /** * 根据已合并名称查询合并后的数据 * @param type * @param projectId * @param mergedName * @return * @throws IOException */ private List> searchChild(Integer type, Integer projectId, String mergedName) throws IOException { SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); List queries = new ArrayList<>(); if (type == 0) { //合并申请人 Query idQ1 = QueryBuilders.term(i -> i.field("merge_applicant.project_id").value(projectId)); Query q1 = QueryBuilders.term(i -> i.field("merge_applicant.name.raw").value(mergedName)); Query bool = QueryBuilders.bool(i -> i.must(idQ1, q1)); Query query1 = QueryBuilders.nested(i -> i.path("merge_applicant").query(bool)); //合并权利人 Query idQ2 = QueryBuilders.term(i -> i.field("merge_right_holder.project_id").value(projectId)); Query q2 = QueryBuilders.term(i -> i.field("merge_right_holder.name.raw").value(mergedName)); Query bool1 = QueryBuilders.bool(i -> i.must(idQ2, q2)); Query query2 = QueryBuilders.nested(i -> i.path("merge_right_holder").query(bool1)); queries.add(query1); queries.add(query2); } else { Query idQ = QueryBuilders.term(i -> i.field("merge_inventor.project_id").value(projectId)); Query q = QueryBuilders.term(i -> i.field("merge_inventor.name.raw").value(mergedName)); Query bool = QueryBuilders.bool(i -> i.must(idQ, q)); Query query = QueryBuilders.nested(i -> i.path("merge_inventor").query(bool)); queries.add(query); } Query query = QueryBuilders.bool(i -> i.should(queries)); builder.query(query); builder.size(1000); builder.trackTotalHits(TrackHits.of(i -> i.enabled(true))); SearchResponse response = client.search(builder.build(), Patent.class); return response.hits().hits(); } /** * 合并人员详情 * * @param vo * @return */ public MergePersonQueryDTO selectMergePersonDetail(MergePersonIdVO vo) { MergePersonQueryDTO dto = new MergePersonQueryDTO(); MergePerson person = mergePersonMapper.selectById(vo.getId()); if (ObjectUtil.isNotEmpty(person)) { BeanUtils.copyProperties(person, dto); List names = JSONArray.parseArray(person.getMergedName(), String.class); dto.setMergedName(names); } return dto; } /** * 获取所有发明人/权利人/申请人 * * @param vo * @return * @throws Exception */ public Records getAllMergePerson(GetAllPersonVO vo) throws Exception { Integer projectId = vo.getProjectId(); Long pageNum = vo.getPageNum(); Long pageSize = vo.getPageSize(); Integer type = vo.getType(); String condition = vo.getSearchQuery(); //es获取的名称 List personList = new ArrayList<>(); SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); String operate = ""; if (StringUtils.isNotEmpty(condition)) { //1. 解析检索条件 treeNode tree = expressManager.getInstance().Parse(condition, false); operateNode operateNode = (operateNode) tree; operate = operateNode.getoperate().getShowName(); //3. 从es中检索数据 Query q = formatQueryService.EsQueryToQuery((operateNode) tree, "patent", projectId); builder.query(q); if (type == 0) { this.loadAppAndRightAgg(builder,pageNum.intValue(),pageSize.intValue()); } else { this.loadInventorAgg(builder,pageNum.intValue(),pageSize.intValue()); } } else { if (type == 0) { //申请人 Query query = this.loadQueryByType(type, projectId); builder.query(query); this.loadAppAndRightAgg(builder,pageNum.intValue(),pageSize.intValue()); } else { Query query = this.loadQueryByType(type, projectId); builder.query(query); this.loadInventorAgg(builder,pageNum.intValue(),pageSize.intValue()); } } builder.trackTotalHits(i -> i.enabled(true)); SearchResponse response = client.search(builder.build(), Patent.class); Aggregate totalAgg = response.aggregations().get("totalAgg"); Aggregate totalAggregate = totalAgg.nested().aggregations().get("statsBucket"); long total = totalAggregate.statsBucket().count(); Aggregate totalAgg1 = null; if (type == 0) { totalAgg1 = response.aggregations().get("totalAgg1"); Aggregate totalAggregate1 = totalAgg1.nested().aggregations().get("statsBucket1"); long count = totalAggregate1.statsBucket().count(); total = Math.max(total, count); } List mergeList = new ArrayList<>(); if (StringUtils.isNotEmpty(condition)) { Aggregate terms = totalAgg.nested().aggregations().get("terms"); List termsBucketList = terms.sterms().buckets().array(); Aggregate terms1 = null; if (type == 0) { terms1 = totalAgg1.nested().aggregations().get("terms1"); List termsBucketList1 = terms1.sterms().buckets().array(); termsBucketList.addAll(termsBucketList1); } if (condition.contains("AND") && operate.equals("AND")) { String[] parts = condition.split(" AND "); for (String part : parts) { List expresses = getConditionExpress(part); List merges = termsBucketList.stream().map(StringTermsBucket::key).map(FieldValue::stringValue).distinct() .filter(value -> expresses.stream().anyMatch(express -> value.contains(express.toUpperCase(Locale.ROOT)))) .collect(Collectors.toList()); total = total > merges.size() ? merges.size() : total; merges = merges.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList()); if (CollectionUtils.isEmpty(mergeList)) { mergeList.addAll(merges); } else { merges.retainAll(mergeList); mergeList = new ArrayList<>(merges); total = total > mergeList.size() ? mergeList.size() : total; } } } else { List expresses = getConditionExpress(condition); List merges = termsBucketList.stream().map(StringTermsBucket::key).map(FieldValue::stringValue).distinct() .filter(value -> expresses.stream().anyMatch(express -> value.contains(express.toUpperCase(Locale.ROOT)))) .collect(Collectors.toList()); total = total > merges.size() ? merges.size() : total; merges = merges.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList()); mergeList.addAll(merges); } } else { loadMergeList(type, response, mergeList); } List nameList = mergeList.stream().distinct().collect(Collectors.toList()); if (!CollectionUtils.isEmpty(nameList)) { personList = this.loadMergedDetail(nameList, projectId, type); } List collect = personList.stream().filter(i -> !StringUtils.isEmpty(i.getName())).collect(Collectors.toList()); while (collect.size() > pageSize) { collect.remove(collect.size() - 1); // 从列表末尾开始删除 } List list = collect.stream().sorted(Comparator.comparing(GetAllPersonDTO::getName)).collect(Collectors.toList()); Records records = new Records(); records.setCurrent(pageNum); records.setSize(pageSize); records.setData(list); records.setTotal(total); return records; } /** * 发明人/权利人/申请人合并记录删除 * * @param vo * @return * @throws Exception */ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class) public Integer delMergePerson(MergePersonIdVO vo) throws Exception { Integer type = vo.getType(); //1.查询合并记录 MergePerson mergePerson = mergePersonMapper.selectById(vo.getId()); //合并后的名称 String name = mergePerson.getName(); //专题库id Integer projectId = mergePerson.getProjectId(); //2.查询合并后的数据 List> hits = searchChild(type, projectId, name); List patentIds = new ArrayList<>(); for (Hit hit : hits) { String routing = hit.routing(); patentIds.add(routing); } //3.删除原子文档 deleteChild(patentIds, type, projectId); //4.查询父文档拿出对应type的数据后添加新的子文档 searchPatent(patentIds, type, projectId); //5.删除合并记录 mergePersonMapper.deleteById(vo.getId()); return vo.getId(); } public List loadMergedDetail(List nameList, Integer projectId, Integer type) { List personList = new ArrayList<>(); for (String name : nameList) { MergePerson person = mergePersonMapper.selectOne(new LambdaQueryWrapper() .eq(MergePerson::getProjectId, projectId) .eq(MergePerson::getType, type) .eq(MergePerson::getName, name)); if (!ObjectUtils.isEmpty(person)) { GetAllPersonDTO dto = new GetAllPersonDTO(); dto.setName(name); dto.setMergeId(person.getId()); dto.setProjectId(person.getProjectId()); dto.setType(person.getType()); dto.setRemark(person.getRemark()); dto.setAbbreviation(person.getAbbreviation()); dto.setCountry(person.getCountry()); dto.setProvince(person.getProvince()); dto.setAddress(person.getAddress()); personList.add(dto); } else { GetAllPersonDTO dto = new GetAllPersonDTO(); dto.setName(name); personList.add(dto); } } return personList; } public void loadMergeList(Integer type,SearchResponse response,List mergeList) { if (type == 0) { Aggregate agg = response.aggregations().get("Agg"); Aggregate nestedAgg = agg.nested().aggregations().get("nestedAgg"); List buckets = nestedAgg.sterms().buckets().array(); Aggregate rightAgg = response.aggregations().get("rightAgg"); Aggregate rightNestedAgg = rightAgg.nested().aggregations().get("rightNestedAgg"); List bucketList = rightNestedAgg.sterms().buckets().array(); if (buckets.size() >= bucketList.size()) { for (StringTermsBucket bucket : buckets) { String value = bucket.key().stringValue(); mergeList.add(value); } for (StringTermsBucket bucket : bucketList) { String value = bucket.key().stringValue(); mergeList.add(value); } } else { for (StringTermsBucket bucket : bucketList) { String value = bucket.key().stringValue(); mergeList.add(value); } for (StringTermsBucket bucket : buckets) { String value = bucket.key().stringValue(); mergeList.add(value); } } } else { Aggregate inventorAgg = response.aggregations().get("Agg"); Aggregate inventorNestedAgg = inventorAgg.nested().aggregations().get("nestedAgg"); List bucketList = inventorNestedAgg.sterms().buckets().array(); if (!CollectionUtils.isEmpty(bucketList)) { for (StringTermsBucket bucket : bucketList) { String value = bucket.key().stringValue(); mergeList.add(value); } } } } public Query loadQueryByType(Integer type,Integer projectId) { Map map = new HashMap<>(); Query q1 = QueryBuilders.term(i -> i.field("merge_applicant.project_id").value(projectId)); Query nestedQ1 = QueryBuilders.nested(i -> i.path("merge_applicant").query(q1)); Query q2 = QueryBuilders.term(i -> i.field("merge_right_holder.project_id").value(projectId)); Query nestedQ2 = QueryBuilders.nested(i -> i.path("merge_right_holder").query(q2)); Query bool = QueryBuilders.bool(i -> i.should(nestedQ1, nestedQ2)); map.put(0, bool); Query q = QueryBuilders.term(i -> i.field("merge_inventor.project_id").value(projectId)); Query nestedQ = QueryBuilders.nested(i -> i.path("merge_inventor").query(q)); map.put(2, nestedQ); return map.get(type); } public void loadAppAndRightAgg(SearchRequest.Builder builder, Integer pageNum, Integer pageSize) { Aggregation bucketSort = AggregationBuilders.bucketSort(i -> i.from((pageNum - 1) * pageSize).size(pageSize)); Aggregation termAgg = new Aggregation.Builder().terms(i -> i.field("merge_applicant.name.raw").size(100000)) .aggregations(new HashMap() {{ put("termAgg", bucketSort); }}).build(); Aggregation aggregation = new Aggregation.Builder().nested(new NestedAggregation.Builder(). path("merge_applicant").build()) .aggregations(new HashMap() {{ put("nestedAgg", termAgg); }}).build(); builder.aggregations("Agg", aggregation); //对聚合结果统计出总数 Aggregation terms = AggregationBuilders.terms(i -> i.field("merge_applicant.name.raw").size(100000)); BucketsPath bucketsPath = BucketsPath.of(i -> i.single("terms>_count")); Aggregation statsBucket = AggregationBuilders.statsBucket(i -> i.bucketsPath(bucketsPath)); Aggregation totalAgg = new Aggregation.Builder().nested(new NestedAggregation.Builder(). path("merge_applicant").build()) .aggregations(new HashMap() {{ put("terms", terms); put("statsBucket", statsBucket); }}).build(); builder.aggregations("totalAgg", totalAgg); //权利人 Aggregation bucketSort1 = AggregationBuilders.bucketSort(i -> i.from((pageNum - 1) * pageSize).size(pageSize)); Aggregation termAgg1 = new Aggregation.Builder().terms(i -> i.field("merge_right_holder.name.raw").size(100000)) .aggregations(new HashMap() {{ put("rightTermAgg", bucketSort1); }}).build(); Aggregation aggregation1 = new Aggregation.Builder().nested(new NestedAggregation.Builder(). path("merge_right_holder").build()) .aggregations(new HashMap() {{ put("rightNestedAgg", termAgg1); }}).build(); builder.aggregations("rightAgg", aggregation1); // //对聚合结果统计出总数 Aggregation terms1 = AggregationBuilders.terms(i -> i.field("merge_right_holder.name.raw").size(100000)); BucketsPath bucketsPath1 = BucketsPath.of(i -> i.single("terms1>_count")); Aggregation statsBucket1 = AggregationBuilders.statsBucket(i -> i.bucketsPath(bucketsPath1)); Aggregation totalAgg1 = new Aggregation.Builder().nested(new NestedAggregation.Builder(). path("merge_right_holder").build()) .aggregations(new HashMap() {{ put("terms1", terms1); put("statsBucket1", statsBucket1); }}).build(); builder.aggregations("totalAgg1", totalAgg1); } public void loadInventorAgg(SearchRequest.Builder builder, Integer pageNum, Integer pageSize) { Aggregation bucketSort = AggregationBuilders.bucketSort(i -> i.from((pageNum - 1) * pageSize).size(pageSize)); Aggregation termAgg = new Aggregation.Builder().terms(i -> i.field("merge_inventor.name.raw").size(100000)) .aggregations(new HashMap() {{ put("termAgg", bucketSort); }}).build(); Aggregation aggregation = new Aggregation.Builder().nested(new NestedAggregation.Builder(). path("merge_inventor").build()) .aggregations(new HashMap() {{ put("nestedAgg", termAgg); }}).build(); builder.aggregations("Agg", aggregation); //对聚合结果统计出总数 Aggregation terms = AggregationBuilders.terms(i -> i.field("merge_inventor.name.raw").size(100000)); BucketsPath bucketsPath = BucketsPath.of(i -> i.single("terms>_count")); Aggregation statsBucket = AggregationBuilders.statsBucket(i -> i.bucketsPath(bucketsPath)); Aggregation totalAgg = new Aggregation.Builder().nested(new NestedAggregation.Builder(). path("merge_inventor").build()) .aggregations(new HashMap() {{ put("terms", terms); put("statsBucket", statsBucket); }}).build(); builder.aggregations("totalAgg", totalAgg); } private List getConditionExpress(String input) { // 编写正则表达式来匹配 = 后面的双括号内的内容 String regex = "=\\(\\(([^)]*)\\)\\)"; // 编译正则表达式 Pattern pattern = Pattern.compile(regex); // 创建matcher对象 Matcher matcher = pattern.matcher(input); // 使用List来存储结果,因为数组的大小是固定的 List values = new ArrayList<>(); // 查找所有匹配项 while (matcher.find()) { // 提取双括号中的内容 String content = matcher.group(1); // 将提取的内容添加到列表中 values.add(content); } List list = new ArrayList<>(); List collect = values.stream().filter(cn.cslg.pas.common.utils.StringUtils::isNotEmpty).distinct().collect(Collectors.toList()); for (String s : collect) { List split = splitWithQuotes(s); list.addAll(split); } List list1 = new ArrayList<>(); for (String s : list) { if (s.contains("\"")) { String replace = s.replace("\"", ""); list1.add(replace); } else { list1.add(s); } } return list1.stream().filter(cn.cslg.pas.common.utils.StringUtils::isNotEmpty).distinct().collect(Collectors.toList()); } public static List splitWithQuotes(String input) { List result = new ArrayList<>(); StringBuilder currentPart = new StringBuilder(); boolean inQuotes = false; for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); if (c == '"' || c == '\'') { // 切换引号状态 inQuotes = !inQuotes; // 如果我们不是在引号内,并且前面有内容,则添加当前部分到结果中 if (!inQuotes && currentPart.length() > 0) { result.add(currentPart.toString()); currentPart.setLength(0); // 重置当前部分 } // 引号内的字符直接添加到当前部分 currentPart.append(c); // 如果引号后面紧跟着的是空格,并且我们刚刚离开了引号,则跳过这个空格 if (i + 1 < input.length() && input.charAt(i + 1) == ' ' && !inQuotes) { i++; // 跳过空格 } } else if (c == ' ' && !inQuotes) { // 如果我们在空格处且不在引号内,则添加当前部分到结果中,并重置当前部分 if (currentPart.length() > 0) { result.add(currentPart.toString()); currentPart.setLength(0); } } else { // 其他字符直接添加到当前部分 currentPart.append(c); } } // 添加最后一个部分(如果有的话) if (currentPart.length() > 0) { result.add(currentPart.toString()); } // 将List转换为数组 return result; } //添加子文档 private void addChild(List personList, Integer projectId, String id, String joinName, Integer type) throws Exception { List mergePersonList = createMergePersonList(personList, projectId); // 根据type决定设置哪个字段 Map>> setterMap = new HashMap<>(); setterMap.put(0, (patent, list) -> patent.setMergeApplicant(list)); setterMap.put(1, (patent, list) -> patent.setMergeRightHolder(list)); setterMap.put(2, (patent, list) -> patent.setMergeInventor(list)); BiConsumer> setter = setterMap.getOrDefault(type, (p, l) -> {}); // 通用添加逻辑 String child = addChildCommon(id, joinName, mergePersonList, setter); if (StringUtils.isEmpty(child)) { throw new XiaoShiException("添加子文档失败"); } // 如果type为0,还需要额外添加一个字段 if (type == 0) { setter = setterMap.get(1); // 假设第二个字段是mergeRightHolder String child1 = addChildCommon(id, joinName, mergePersonList, setter); if (StringUtils.isEmpty(child1)) { throw new XiaoShiException("添加子文档失败"); } } } private List createMergePersonList(List personList, Integer projectId) { List mergePersonList = new ArrayList<>(); if (!CollectionUtils.isEmpty(personList)) { for (PatentPerson person : personList) { PatentMergePerson merge = new PatentMergePerson(); merge.setName(person.getName()); merge.setType(person.getType()); merge.setOrder(person.getOrder()); merge.setProjectId(String.valueOf(projectId)); mergePersonList.add(merge); } } return mergePersonList; } private String addChildCommon(String id, String joinName, List mergePersonList, BiConsumer> setter) throws Exception { Patent newPatent = new Patent(); PatentJoin patentJoin = new PatentJoin(); patentJoin.setParent(id); patentJoin.setName(joinName); newPatent.setPatentJoin(patentJoin); setter.accept(newPatent, mergePersonList); return this.addChildToES(newPatent, id); } private void deleteChild(List ids, Integer type, Integer projectId) throws IOException { SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); List queries = new ArrayList<>(); if (type == 0) { //合并申请人 Query q = QueryBuilders.term(i -> i.field("merge_applicant.project_id").value(projectId)); Query query1 = QueryBuilders.nested(i -> i.path("merge_applicant").query(q)); //合并权利人 Query q1 = QueryBuilders.term(i -> i.field("merge_right_holder.project_id").value(projectId)); Query query2 = QueryBuilders.nested(i -> i.path("merge_right_holder").query(q1)); queries.add(query1); queries.add(query2); } else { Query q = QueryBuilders.term(i -> i.field("merge_inventor.project_id").value(projectId)); Query query = QueryBuilders.nested(i -> i.path("merge_inventor").query(q)); queries.add(query); } Query query = QueryBuilders.bool(i -> i.should(queries)); Query idQ = QueryBuilders.ids(i -> i.values(ids)); Query parentQ = QueryBuilders.hasParent(i -> i.parentType("patent").query(idQ)); Query bool = QueryBuilders.bool(i -> i.must(parentQ, query)); builder.query(bool); builder.size(1000); builder.trackTotalHits(TrackHits.of(i -> i.enabled(true))); SearchResponse response = client.search(builder.build(), Patent.class); List> hits = response.hits().hits(); List idList = new ArrayList<>(); for (Hit hit : hits) { String id = hit.id(); idList.add(id); } //删除子文档 delete(idList); } //查询专利父文档 private void searchPatent(List ids, Integer type, Integer projectId) throws Exception { SearchRequest.Builder builder = new SearchRequest.Builder(); //设置查询索引 builder.index("patent"); Query query = QueryBuilders.ids(i -> i.values(ids)); builder.query(query); builder.size(1000); builder.trackTotalHits(TrackHits.of(i -> i.enabled(true))); SearchResponse response = client.search(builder.build(), Patent.class); List> hits = response.hits().hits(); for (Hit hit : hits) { String id = hit.id(); Patent patent = hit.source(); if (type == 0) { if (!CollectionUtils.isEmpty(patent.getApplicant())) { this.addChild(patent.getApplicant(), projectId, id, "merge_applicat",type); } if (!CollectionUtils.isEmpty(patent.getRightHolder())) { addChild(patent.getRightHolder(), projectId, id, "merge_right_holder",type); } } else { if (!CollectionUtils.isEmpty(patent.getInventor())) { addChild(patent.getInventor(), projectId, id, "merge_inventor",type); } } } } /** * 获取所有国家列表查询 * * @return */ public List getAllCountry() { List list = new ArrayList<>(); List countries = systemDictMapper.selectList(new LambdaQueryWrapper() .eq(SystemDict::getType, "COUNTRIES")); if (!CollectionUtils.isEmpty(countries)) { countries.forEach(county -> { GetAllCountryDTO dto = new GetAllCountryDTO(); dto.setLabel(county.getLabel()); dto.setValue(county.getValue()); dto.setType(county.getType()); list.add(dto); }); } return list; } /** * 获取国内省份列表查询 * * @return */ public List getAllProvince() { List list = new ArrayList<>(); List countries = systemDictMapper.selectList(new LambdaQueryWrapper() .eq(SystemDict::getType, "PROVINCE")); if (!CollectionUtils.isEmpty(countries)) { countries.forEach(county -> { GetAllCountryDTO dto = new GetAllCountryDTO(); dto.setLabel(county.getLabel()); dto.setValue(county.getValue()); dto.setType(county.getType()); list.add(dto); }); } return list; } /** * @param patent * @throws Exception */ public String addChildToES(Patent patent, String id) throws Exception { IndexResponse indexResponse = client.index(i -> i .index("patent") .routing(id) //传入user对象 .document(patent).refresh(Refresh.True) ); return indexResponse.id(); } //更新patent public Integer updateChild(Patent patent, String id, String routing) { UpdateRequest req; req = UpdateRequest.of( b -> b.index("patent") .id(id) .routing(routing) .doc(patent).refresh(Refresh.True) ); try { client.update(req, Patent.class); return 1; } catch (IOException e) { return -1; } } public Integer delete(List ids) { Query query = QueryBuilders.ids(n -> n.values(ids)); DeleteByQueryRequest request = DeleteByQueryRequest.of(i -> i.index("patent").refresh(true).query(query)); try { client.deleteByQuery(request); return 1; } catch (IOException e) { throw new XiaoShiException("删除失败"); } } /** * 删除申请人/权利人/发明人合并名称 * * @param id * @return */ public Integer delSingleMerge(String id, Integer type, String name) { String source = ""; if (type == 0) { source = "if (ctx._source.merge_applicant != null) { ctx._source.merge_applicant.removeIf(item -> item.name == params.name); } if (ctx._source.merge_right_holder != null) { ctx._source.merge_right_holder .removeIf(item -> item.name == params.name); }"; } else { source = "if (ctx._source.merge_inventor != null) { ctx._source.merge_inventor.removeIf(item -> item.name == params.name); }"; } String finalSource = source; InlineScript inlineScript = InlineScript.of(i -> i.lang("painless").params("name", JsonData.of(name)).source(finalSource)); Script script = Script.of(i -> i.inline(inlineScript)); Query query = QueryBuilders.term(i -> i.field("_id").value(id)); UpdateByQueryRequest request = UpdateByQueryRequest.of(i -> i.index("patent").script(script).query(query)); try { client.updateByQuery(request); return 1; } catch (IOException e) { return -1; } } public Integer add(String id, Integer type, List mergePersonList) { Integer flag = null; for (PatentMergePerson mergePerson : mergePersonList) { Map map = new HashMap<>(); map.put("name", JsonData.of(mergePerson.getName())); map.put("project_id", JsonData.of(mergePerson.getProjectId())); map.put("type", JsonData.of(mergePerson.getType())); map.put("order", JsonData.of(mergePerson.getOrder())); String source = ""; if (type == 0) { source = "if (ctx._source.merge_applicant != null) {ctx._source.merge_applicant.add(params.data)} else { List list = new ArrayList();list.add(params.data);ctx._source.merge_applicant = list;}" + "if (ctx._source.merge_right_holder != null) { ctx._source.merge_right_holder.add(params.data)} else { List list = new ArrayList();list.add(params.data);ctx._source.merge_right_holder = list;}"; } else { source = "if (ctx._source.merge_inventor != null) {ctx._source.merge_inventor.add(params.data)} else { List list = new ArrayList();list.add(params.data);ctx._source.merge_inventor = list;}"; } String finalSource = source; InlineScript inlineScript = InlineScript.of(i -> i.lang("painless").params("data", JsonData.of(map)).source(finalSource)); Script script = Script.of(i -> i.inline(inlineScript)); Query query = QueryBuilders.term(i -> i.field("_id").value(id)); UpdateByQueryRequest request = UpdateByQueryRequest.of(i -> i.index("patent").script(script).query(query)); try { client.updateByQuery(request); flag += 1; } catch (IOException e) { flag += -1; } } return flag; } public Integer edit(String id, Integer type, String oldName, String newName) { String source = ""; if (type == 0) { source = "if (ctx._source.merge_applicant != null) {for (item in ctx._source.merge_applicant) {if(item['name']==params.oldName){item['name']=params.newName}}}" + "if (ctx._source.merge_right_holder != null) {for (item in ctx._source.merge_right_holder) {if(item['name']==params.oldName){item['name']=params.newName}}}"; } else { source = "if (ctx._source.merge_inventor != null) {for (item in ctx._source.merge_inventor) {if(item['name']==params.oldName){item['name']=params.newName}}}"; } String finalSource = source; Map map = new HashMap<>(); map.put("oldName", JsonData.of(oldName)); map.put("newName", JsonData.of(newName)); InlineScript inlineScript = InlineScript.of(i -> i.lang("painless").params(map).source(finalSource)); Script script = Script.of(i -> i.inline(inlineScript)); Query query = QueryBuilders.term(i -> i.field("_id").value(id)); UpdateByQueryRequest request = UpdateByQueryRequest.of(i -> i.index("patent").script(script).query(query)); try { client.updateByQuery(request); return 1; } catch (IOException e) { return -1; } } /** * 删除申请人/权利人/发明人合并名称 * * @param patent * @param id * @return */ public Integer delMergePerson(Patent patent, String id, Integer type, String name) { String source = ""; if (type == 0) { source = "if (ctx._source.merge_applicant != null) { ctx._source.merge_applicant.removeIf(item -> item.name == params.name); } if (ctx._source.merge_right_holder != null) { ctx._source.merge_right_holder .removeIf(item -> item.name == params.name); }"; } else { source = "if (ctx._source.merge_inventor != null) { ctx._source.merge_inventor.removeIf(item -> item.name == params.name); }"; } String finalSource = source; InlineScript inlineScript = InlineScript.of(i -> i.lang("painless").params("name", JsonData.of(name)).source(finalSource)); Script script = Script.of(i -> i.inline(inlineScript)); Query query = QueryBuilders.term(i -> i.field("_id").value(id)); UpdateByQueryRequest request = UpdateByQueryRequest.of(i -> i.index("patent").script(script).query(query)); try { client.updateByQuery(request); return 1; } catch (IOException e) { return -1; } } }