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;

}
相关推荐
悟空爬虫-彪哥1 分钟前
2026 Python UI 框架选择指南:从 Streamlit 到 Pyside6 的四层体系
开发语言·python·ui
weixin_408717773 分钟前
SQL中JOIN不同存储引擎表的影响_索引兼容性与查询性能评估
jvm·数据库·python
qq_189807034 分钟前
如何让导航栏的下落动画效果更慢?
jvm·数据库·python
梦无矶4 分钟前
快速设置uv默认源为国内镜像
数据库·redis·后端·python·uv
m0_515098426 分钟前
HTML函数在低分辨率屏幕能正常编写吗_显示硬件最低适配说明【方法】
jvm·数据库·python
m0_7489203610 分钟前
如何利用宝塔面板设置网站限流策略_防止恶意高并发请求
jvm·数据库·python
bigcarp12 分钟前
windows server 2012上安装EdgeWebView2以支持pywebview项目
python
测试员周周13 分钟前
【CrewAI系列2】CrewAI 环境搭不好?纯小白从零部署指南,10 分钟搞定(命令可复制)
人工智能·python
m0_7349497917 分钟前
C#怎么操作Redis缓存 C#如何用StackExchange.Redis连接和操作Redis数据【数据库】
jvm·数据库·python
2301_8148098618 分钟前
PHP源码开发推荐使用哪种机箱_散热与扩展平衡选择【教程】
jvm·数据库·python