优化综合浏览数据资源查询条件包含置标标签后数据库查询慢的问题

master
guoxin 1 year ago
parent 0b74f2da21
commit 88c0238889
  1. 70
      shandan-browser/src/main/java/com/keyware/shandan/browser/service/MetadataSearchService.java
  2. 2
      shandan-control/src/main/resources/application-dev.yml
  3. 45
      shandan-system/src/main/java/com/keyware/shandan/bianmu/mapper/DirectoryResourceMapper.java

@ -4,11 +4,11 @@ import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.keyware.shandan.bianmu.entity.DataLabelsVo;
import com.keyware.shandan.bianmu.entity.DirectoryResource;
import com.keyware.shandan.bianmu.entity.DirectoryVo;
import com.keyware.shandan.bianmu.enums.DirectoryType;
import com.keyware.shandan.bianmu.enums.ReviewStatus;
import com.keyware.shandan.bianmu.mapper.DirectoryResourceMapper;
import com.keyware.shandan.bianmu.service.DataLabelsService;
import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.browser.entity.PageVo;
import com.keyware.shandan.browser.entity.SearchConditionVo;
@ -20,6 +20,7 @@ import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -36,26 +37,40 @@ public class MetadataSearchService {
@Autowired
private DirectoryResourceMapper directoryResourceMapper;
@Autowired
private DataLabelsService labelsService;
public PageVo<DirectoryResource> searchByCondition(String directoryId, SearchConditionVo condition) {
QueryWrapper<DirectoryResource> queryWrapper = buildQueryWrapper(directoryId, condition);
return PageVo.pageConvert(directoryResourceMapper.selectPage(new Page<>(condition.getPage(), condition.getSize()), queryWrapper));
DirectoryVo parent = directoryService.getById(directoryId);
Assert.notNull(parent, "资源目录未找到");
QueryWrapper<DirectoryResource> queryWrapper = buildQueryWrapper(parent, condition);
List<DataLabelsVo> labels = new ArrayList<>();
condition.getConditions().stream().filter(item -> "markTag".equals(item.getFieldName())).findFirst().ifPresent(item -> {
String tagIds = item.getFieldValue();
labels.addAll(labelsService.listByIds(Arrays.asList(tagIds.split(","))));
});
labels.forEach(label -> label.setIdPath(label.getIdPath() + label.getId() + "/"));
Page<DirectoryResource> page = directoryResourceMapper.customSelectPage(new Page<>(condition.getPage(), condition.getSize()), parent.getDirectoryPath() + "/", labels, queryWrapper);
return PageVo.pageConvert(page);
}
public List<DirectoryResource> searchAllListByCondition(String directoryId, SearchConditionVo condition) {
QueryWrapper<DirectoryResource> queryWrapper = buildQueryWrapper(directoryId, condition);
return directoryResourceMapper.selectList(queryWrapper);
DirectoryVo parent = directoryService.getById(directoryId);
Assert.notNull(parent, "资源目录未找到");
QueryWrapper<DirectoryResource> queryWrapper = buildQueryWrapper(parent, condition);
List<DataLabelsVo> labels = new ArrayList<>();
condition.getConditions().stream().filter(item -> "markTag".equals(item.getFieldName())).findFirst().ifPresent(item -> {
String tagIds = item.getFieldValue();
labels.addAll(labelsService.listByIds(Arrays.asList(tagIds.split(","))));
});
labels.forEach(label -> label.setIdPath(label.getIdPath() + label.getId() + "/"));
return directoryResourceMapper.customSelectList(parent.getDirectoryPath() + "/", labels, queryWrapper);
}
public QueryWrapper<DirectoryResource> buildQueryWrapper(String directoryId, SearchConditionVo condition) {
public QueryWrapper<DirectoryResource> buildQueryWrapper(DirectoryVo dir, SearchConditionVo condition) {
QueryWrapper<DirectoryResource> queryWrapper = new QueryWrapper<>();
DirectoryVo dir = directoryService.getById(directoryId);
Assert.notNull(dir, "资源目录未找到");
// 查找当前目录下审核通过的下级目录
List<String> parentIds = StreamUtil.as(getAllDirChildren(dir)).map(DirectoryVo::getId).toList();
queryWrapper.in("PARENT_ID", parentIds);
queryWrapper.and(condition.getConditions().size() > 0, wrapper -> {
queryWrapper.and(!condition.getConditions().isEmpty(), wrapper -> {
StreamUtil.as(condition.getConditions()).forEach(item -> {
switch (item.getFieldName()) {
case "inputDate":
@ -84,23 +99,12 @@ public class MetadataSearchService {
wrapper.and(StringUtils.hasText(value.trim()), qw -> {
if ("eq".equals(item.getLogicJudgement())) {
qw.eq("RESOURCE_NAME", value.trim())/*.or().eq("RESOURCE_COMMENT", value.trim())*/;
}else{
} else {
qw.like("RESOURCE_NAME", value.trim())/*.or().like("RESOURCE_COMMENT", value.trim())*/;
}
});
}
}
break;
case "markTag":
String tagIds = item.getFieldValue();
List<String> ids = Arrays.asList(tagIds.split(","));
if (!ids.isEmpty()) {
StringBuilder existsSql = new StringBuilder("select 1 from (select ENTITY_ID, WM_CONCAT(LABEL_ID) LABEL_IDS from B_DATA_LABEL_ENTITY DLN where DLN.ENTITY_ID = V_DIRECTORY_RESOURCE.ID group by ENTITY_ID) tmp1");
List<String> andSqlList = ids.stream().map(id -> "tmp1.LABEL_IDS like '%" + id + "%'").collect(Collectors.toList());
existsSql.append(" where ").append(String.join(" and ", andSqlList));
wrapper.exists(existsSql.toString());
}
break;
default:
}
@ -121,18 +125,4 @@ public class MetadataSearchService {
}
return queryWrapper;
}
/**
* 获取指定目录下 所有审核通过的下级目录集合
*
* @param parent 上级目录
* @return 目录集合
*/
private List<DirectoryVo> getAllDirChildren(DirectoryVo parent) {
QueryWrapper<DirectoryVo> wrapper = new QueryWrapper<>();
wrapper.likeRight("DIRECTORY_PATH", parent.getDirectoryPath())
.in("DIRECTORY_TYPE", DirectoryType.DIRECTORY, DirectoryType.LINK_DIR)
.in("REVIEW_STATUS", ReviewStatus.PASS, ReviewStatus.SUBMITTED);
return directoryService.list(wrapper);
}
}

@ -47,4 +47,4 @@ project:
logging:
level:
com.keyware: info
com.keyware: debug

@ -1,9 +1,54 @@
package com.keyware.shandan.bianmu.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.keyware.shandan.bianmu.entity.DataLabelsVo;
import com.keyware.shandan.bianmu.entity.DirectoryResource;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.ResultType;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface DirectoryResourceMapper extends BaseMapper<DirectoryResource> {
@Select("<script>" +
" SELECT DISTINCT TT.* FROM (" +
" SELECT * FROM V_DIRECTORY_RESOURCE VDR WHERE DIRECTORY_PATH LIKE (#{dirPath} || '%') AND EXISTS(SELECT 1 FROM B_DIRECTORY D1 WHERE D1.ID = VDR.PARENT_ID AND D1.REVIEW_STATUS IN ('PASS','SUBMITTED'))" +
" ) TT " +
" <when test='labels != null and labels.size > 0'>" +
" LEFT JOIN B_DATA_LABEL_ENTITY DLN ON DLN.ENTITY_ID = TT.ID " +
" WHERE 1=1 " +
" <foreach item=\"label\" collection=\"labels\">" +
" AND (DLN.ID_PATH LIKE (#{label.idPath + label.id + '/'} || '%') OR DLN.ID = #{label.id})" +
" </foreach>" +
" </when>" +
" <when test=\"ew.sqlSegment != null and ew.sqlSegment != '' and ew.sqlSegment != '()'\">" +
" ${ew.sqlSegment}" +
" </when>" +
"</script>")
@ResultType(DirectoryResource.class)
List<DirectoryResource> customSelectList(@Param("dirPath") String dirPath, @Param("labels") List<DataLabelsVo> labels, @Param(Constants.WRAPPER) QueryWrapper<DirectoryResource> queryWrapper);
@Select("<script>" +
" SELECT DISTINCT TT.* FROM (" +
" SELECT * FROM V_DIRECTORY_RESOURCE VDR WHERE DIRECTORY_PATH LIKE (#{dirPath} || '%') AND EXISTS(SELECT 1 FROM B_DIRECTORY D1 WHERE D1.ID = VDR.PARENT_ID AND D1.REVIEW_STATUS IN ('PASS','SUBMITTED'))" +
" ) TT " +
" <when test='labels != null and labels.size > 0'>" +
" LEFT JOIN (SELECT B2.*, B1.ENTITY_ID FROM B_DATA_LABEL_ENTITY B1 INNER JOIN B_DATA_LABELS B2 ON B1.LABEL_ID = B2.ID) DLN ON DLN.ENTITY_ID = TT.ID " +
" WHERE 1=1 " +
" <foreach item=\"label\" collection=\"labels\">" +
" AND (DLN.ID_PATH LIKE (#{label.idPath} || '%') OR DLN.ID = #{label.id})" +
" </foreach>" +
" </when>" +
" <when test=\"ew.sqlSegment != null and ew.sqlSegment != '' and ew.sqlSegment != '()'\">" +
" ${ew.sqlSegment}" +
" </when>" +
"</script>")
@ResultType(DirectoryResource.class)
Page<DirectoryResource> customSelectPage(Page<DirectoryResource> page, @Param("dirPath") String dirPath, @Param("labels") List<DataLabelsVo> labels, @Param(Constants.WRAPPER) QueryWrapper<DirectoryResource> queryWrapper);
}