MongoDB - 构造复杂查询条件执行查询

文章目录

      • [1. 构造 keyword 的查询条件](#1. 构造 keyword 的查询条件)
      • [2. 构造 threatSubType 的查询条件](#2. 构造 threatSubType 的查询条件)
      • [3. 相应的实体类](#3. 相应的实体类)
java 复制代码
/**
 * 查询白名单详情
 *
 * @param offset        第几页开始
 * @param limit         每页显示的最大值
 * @param keyword       模糊搜索值
 * @param order         排序方式(升序/降序)
 * @param sortKey       排序的字段
 * @param threatSubType 告警类型
 * @return 白名单实体列表
 */
List<AlertWhiteEntity> findListByKeyword(
        Integer offset, Integer limit, String keyword, String order,
        String sortKey, List<String> threatSubType
);
java 复制代码
@Override
public List<AlertWhiteEntity> findListByKeyword(
        Integer offset, Integer limit, String keyword, String order,
        String sortKey,
        List<String> threatSubType
) {
    // 开始构造查询条件
    Query query = new Query();
    // 1. 构造 keyword 的查询条件
    if (!StringUtils.isEmpty(keyword)) {
        query.addCriteria(dealKeyword(keyword));
    }
    // 2. 构造排序规则,默认是降序排序 
    Sort.Order orderSort = Sort.Order.desc(sortKey);
    if (Objects.equals(order, ASC)) {
        orderSort = Sort.Order.asc(sortKey);
    }
    // 3. 构造 threatSubType 的查询条件
    getThreatSubTypeFilter(threatSubType, query);
    // 4. 对status按照指定排序规则排序
    query.with(Sort.by(Sort.Order.desc("status"), orderSort));
    // 5. 分页查询
    query.skip((long) (offset - 1) * limit).limit(limit);
    
    // 执行查询
    return incidentMongoTemplate.find(query, AlertWhiteEntity.class);
}

1. 构造 keyword 的查询条件

java 复制代码
private CriteriaDefinition dealKeyword(String keyword) {
    // Java的正则表达式库创建了一个正则表达式模式对象:匹配任意位置包含指定关键字的字符串,并且不区分大小写。
    Pattern pattern = Pattern.compile("^.*" + keyword + ".*$", Pattern.CASE_INSENSITIVE);
    Criteria criteria = new Criteria();
    Criteria[] criteriaArray = null;
    String fullIp = "";
    // ruleList.ruleList 中存在一个元素,该元素满足以下条件:type字段等于"srcIp"或"dstIp",value字段匹配给定的正则表达式pattern
    // creator 字段匹配给定的正则表达式pattern
    // name 字段匹配给定的正则表达式pattern
    // ruleList.ipRange 中存在一个元素,该元素的value满足以下条件: startIp字段小于等于给定的fullIp,endIp字段大于等于给定的fullIp
    if (IpUtil.judgeLegalIp(keyword)) {
        if (IpUtil.judgeIpv6(keyword)) {
            fullIp = IpUtil.formatIpv6Full(keyword);
        } else if (IpUtil.judgeIpv4(keyword)) {
            fullIp = IpUtil.formatIpv4Full(keyword);
        }
        criteriaArray = new Criteria[] {
                new Criteria().and("ruleList.ruleList").elemMatch(
                        new Criteria()
                                .andOperator(new Criteria().orOperator(new Criteria().and("type").is("srcIp"), new Criteria().and("type").is("dstIp")), new Criteria().and("value").regex(pattern))
                ),
                new Criteria().and("creator").regex(pattern),
                new Criteria().and("name").regex(pattern),
                new Criteria().and("ruleList.ipRange").elemMatch(
                        new Criteria().and("value").elemMatch(new Criteria().andOperator(Criteria.where("startIp").lte(fullIp), Criteria.where("endIp").gte(fullIp)))

                )
        };
    // 查询ruleList.ruleList中满足以下条件的元素:type字段等于"srcIp"或者"type"字段等于"dstIp",value字段匹配正则表达式pattern
    // 查询creator字段匹配正则表达式pattern的文档
    // 查询name字段匹配正则表达式pattern的文档
    } else {
        criteriaArray = new Criteria[] {
                new Criteria().and("ruleList.ruleList").elemMatch(
                        new Criteria()
                                .andOperator(new Criteria().orOperator(new Criteria().and("type").is("srcIp"), new Criteria().and("type").is("dstIp")), new Criteria().and("value").regex(pattern))
                ),
                new Criteria().and("creator").regex(pattern),
                new Criteria().and("name").regex(pattern)
        };
    }

    criteria.orOperator(criteriaArray);
    return criteria;
}

2. 构造 threatSubType 的查询条件

java 复制代码
private void getThreatSubTypeFilter(List<String> threatSubType, Query query) {
    // 如果threatSubType不为null或者列表不为空,将"all"添加为列表,代表需要值为查询"全部"的文档
    if (threatSubType != null && threatSubType.size() != 0) {
        if (!threatSubType.contains(ALL)) {
            threatSubType.add(ALL);
        }
        // 查询threatSubTypeId在threatSubType列表中的文档
        query.addCriteria(Criteria.where("threatSubTypeId").in(threatSubType));
    }
    // 查询 deleted 为false 的文档
    query.addCriteria(Criteria.where("deleted").is(false));
}

3. 相应的实体类

java 复制代码
@Data
@Document("t_alert_white_rules")
public class AlertWhiteEntity {
    @JsonProperty("_id")
    @MongoId
    @ApiModelProperty(value = "元api id")
    @JsonSerialize(using = ObjectIdSerializer.class)
    private ObjectId id;

    @Field("whiteId")
    @ApiModelProperty(value = "白名单id")
    private String whiteId;

    @Field("alertType")
    @ApiModelProperty(value = "告警类型,前端使用控制展示哪种模板")
    private String alertType;

    @ApiModelProperty(value = "告警类型,前端使用控制渲染告警类型")
    private String originAlertType;

    @Field("threatSubType")
    @ApiModelProperty(value = "攻击小类数量", example = "{[\"label\":\"aaaa\",\"value\":\"1_2_3\"]}")
    private List<WhiteScreenEntity> threatSubType;

    @Field("threatSubTypeView")
    @ApiModelProperty(value = "攻击小类展示数组", example = "[\"aaa\"]")
    private List<String> threatSubTypeView;

    @Field("threatSubTypeId")
    @ApiModelProperty(value = "攻击小类ID数组", example = "[\"1_2_3\"]")
    private List<String> threatSubTypeId;

    @Field("hostIp")
    @ApiModelProperty(value = "生效主机", example = "1.1.1.1")
    private List<String> hostIp;

    @Field("isHostAll")
    @ApiModelProperty(value = "是否勾选全部")
    private Boolean isHostAll;

    @Field("repeatMd5")
    @ApiModelProperty(value = "用于判断是否重复md5")
    private String repeatMd5;

    @Field("status")
    @ApiModelProperty(value = "状态", notes = "启用enable | 禁用disable")
    private String status;

    @Field("name")
    @ApiModelProperty(value = "规则名称")
    private String name;

    @Field("isUnlimited")
    @ApiModelProperty(value = "是否永久生效", notes = "永久生效1 | 自定义0")
    private Integer isUnlimited;

    @Field("sort_status")
    @ApiModelProperty(value = "分类状态", notes = "status是enable时1 | status是disable时0")
    private Integer sortStatus;

    @Field("reason")
    @ApiModelProperty(value = "备注")
    private String reason;

    @Field("ruleList")
    @ApiModelProperty(value = "规则列表")
    private RuleEntity ruleList;

    @Field("creator")
    @ApiModelProperty(value = "创建人")
    private String creator;

    @Field("creatorId")
    @ApiModelProperty(value = "创建人Id")
    private String creatorId;

    @Field("startTime")
    @ApiModelProperty(value = "开始时间")
    private Long startTime;

    @Field("endTime")
    @ApiModelProperty(value = "结束时间")
    private Long endTime;

    @Field("createTime")
    @ApiModelProperty(value = "创建时间")
    private long createTime;

    @Field("updateTime")
    @ApiModelProperty(value = "更新时间")
    private long updateTime;

    @Field("deleted")
    @ApiModelProperty(value = "是否删除", notes = "否0 | 是1")
    private boolean deleted;
}
java 复制代码
@Data
public class RuleEntity {

    @ApiModelProperty(value = "规则列表")
    private List<RuleInfoEntity<String>> ruleList;

    @ApiModelProperty(value = "IP范围")
    private List<RuleInfoEntity<IpInfoEntity>> ipRange;

    @ApiModelProperty(value = "IOA类型")
    private List<List<RuleInfoEntity<String>>> ioaRuleList;

}
java 复制代码
@AllArgsConstructor
@NoArgsConstructor
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel(description = "匹配规则")
public class RuleInfoEntity<T> implements ValidateAble {

    @ApiModelProperty(value = "匹配字段", required = true, example = "srcIp")
    private String type;

    /***
     * 该值用于处理view进行转换,不接收来自调用者
     */
    @ApiModelProperty(value = "匹配值", required = true)
    private List<T> value;

    @ApiModelProperty(value = "TMG匹配值", required = true)
    private List<T> tmgValue;

    @ApiModelProperty(value = "中文名称", example = "srcIp")
    private String title;

    @ApiModelProperty(value = "匹配模式", required = true, example = "IN")
    private String mode;

    @ApiModelProperty(value = "匹配值")
    private List<String> view;

    @ApiModelProperty(value = "是否忽略大小写")
    private Boolean isIgnorecase;
}
java 复制代码
@Data
public class IpInfoEntity {

    @ApiModelProperty(value = "开始IP")
    private String startIp;

    @ApiModelProperty(value = "结束ip")
    private String endIp;

}
相关推荐
阿蒙Amon1 小时前
【Python小工具】使用 OpenCV 获取视频时长的详细指南
python·opencv·音视频
橘子编程2 小时前
Python-Word文档、PPT、PDF以及Pillow处理图像详解
开发语言·python
蓝婷儿2 小时前
Python 机器学习核心入门与实战进阶 Day 2 - KNN(K-近邻算法)分类实战与调参
python·机器学习·近邻算法
之歆3 小时前
Python-封装和解构-set及操作-字典及操作-解析式生成器-内建函数迭代器-学习笔记
笔记·python·学习
天天爱吃肉82183 小时前
ZigBee通信技术全解析:从协议栈到底层实现,全方位解读物联网核心无线技术
python·嵌入式硬件·物联网·servlet
Allen_LVyingbo4 小时前
Python常用医疗AI库以及案例解析(2025年版、上)
开发语言·人工智能·python·学习·健康医疗
智能砖头4 小时前
LangChain 与 LlamaIndex 深度对比与选型指南
人工智能·python
热爱生活的猴子4 小时前
Poetry 在 Linux 和 Windows 系统中的安装步骤
linux·运维·windows
风逸hhh5 小时前
python打卡day58@浙大疏锦行
开发语言·python
烛阴6 小时前
一文搞懂 Python 闭包:让你的代码瞬间“高级”起来!
前端·python