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

这篇具有很好参考价值的文章主要介绍了MongoDB - 构造复杂查询条件执行查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

/**
 * 查询白名单详情
 *
 * @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
);
@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 的查询条件

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 的查询条件

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. 相应的实体类

@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;
}
@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;

}
@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;
}
@Data
public class IpInfoEntity {

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

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

}

文章来源地址https://www.toymoban.com/news/detail-681862.html

到了这里,关于MongoDB - 构造复杂查询条件执行查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • mysql数据库表的多条件查询

    select可以返回多条数据也可以返回一条数据 如果要查询所有的字段可以用 *****代替 where后面跟的是筛选条件(可选) N 是返回的数据条数(可选) M 是数据的偏移量(可选) 例如:在职位招聘表中获取在长沙雨花区的前10条信息 通用语法 : 询语句中你可以使用一个或者多个

    2024年02月11日
    浏览(76)
  • 数据库信息速递 MONGODB 6.0 的新特性,更多的查询函数,加密查询,与时序数据集合 (译)...

    开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到3群(共1000人左右 1 + 2 + 3),最近发展的速度比较快,2群除特殊情况,不在添加

    2024年02月16日
    浏览(47)
  • Python MySQL 数据库查询:选择数据、使用筛选条件、防止 SQL 注入

    要从MySQL中的表格中选择数据,请使用\\\"SELECT\\\"语句: 示例选择\\\"customers\\\"表格中的所有记录,并显示结果: 注意 :我们使用 fetchall() 方法,该方法从上次执行的语句中获取所有行。 要仅选择表格中的某些列,请使用\\\"SELECT\\\"语句,后跟列名: 示例仅选择name和address列: 如果您只对

    2024年02月05日
    浏览(95)
  • 【数据库】通过实例讲清楚,Mongodb的增删查改,分组查询,聚合查询aggregate

    目录 一.基础概念 二.数据库的管理 1.创建数据库 2.删除数据库 二.集合的管理 1.显示所有集合 2.创建集合 3.删除当前集合 4.向集合中插入元素 三.文档的管理 1.文档插入 2.文档的更新 3.文档的删除 4.文档查询 (1)查询基本语法: (2)查询table2集合下的所有文档 (3)查询t

    2024年02月10日
    浏览(42)
  • Mysql 数据库DQL 数据查询语言 SELECT 基本查询、条件查询、聚合查询、分组查询、排序查询、分页查询——包含DQL所有查询语句。吐血分享。

    DQL:数据查询语言; 用来对表内的数据进行查找 。Database Query Language SQL语句分为:基本查询、条件查询、聚合查询、分组查询、排序查询、分页查询。  可以发现name字段就只剩下一个张三了;   条件: 条件查询—比较运算符 比较运算符 功能 大于 = 大于等于 小于 = 小于等

    2024年01月19日
    浏览(56)
  • ElasticSearch多条件复杂查询实现

    前面实现方式和但条件一致 查询代码区别如下 注释里面标注了或者和and那两行的区别 网站链接 elasticsearch(ES)在SpringBoot中的复杂查询(多条件分页查询以及聚合查询)_尺规作图的博客-CSDN博客_springboot 整合es多条件

    2024年02月04日
    浏览(48)
  • 【JaveWeb教程】(20) MySQL数据库开发之 基本查询、条件查询、聚合函数、分组查询、排序查询、分页查询 详细代码示例讲解

    在上次学习的内容中,我们讲解了: 使用DDL语句来操作数据库以及表结构(数据库设计) 使用DML语句来完成数据库中数据的增、删、改操作(数据库操作) 我们今天还是继续学习数据库操作方面的内容:查询(DQL语句)。 查询操作我们分为两部分学习: DQL语句-单表操作

    2024年02月02日
    浏览(85)
  • 分布式数据库NoSQL(四)——MongoDB 之聚合函数查询统计

    MongoDB 中聚合( aggregate )主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果,通常由聚合管道操作符和聚合表达式组合,完成数据处理。功能有点类似 Sql 语句中的 sum()、agv() 等。 目录 第1关:聚合管道操作符将文档定制格式输出(一) 常用聚合管道操作符

    2024年02月09日
    浏览(49)
  • MongoDB【CRUD练习-条件查询-文档关系】

    这里会学习到一个数据类型: 数组 ,这里的语法和JavaScript十分相似。数组使用push来添加数据。 这里还会学到比较运算符:小于:lt ,等于:eq,大于: gt,小于等于: lte,大于等于: gte。和我们shell编程的比较运算符很像。 文档之间有三种: 一对一 夫妻 一对多/多对一

    2024年02月11日
    浏览(59)
  • MyBatis-Plus使用条件构造器实现不同条件的查询,更新删除操作

    Wrapper 是所有条件构造器的父类,作用是生成条件语句,即where后面的sql子句 在调用查询,更新,删除操作时,需要根据条件进行判断,可以使用条件构造器进行组合条件,生成where后面条件子句 QueryWrapper,UpdateWrapper LambdaQueryWrapper,LambdaUpdateWrapper UpdateWrapper提供了set方法,可以

    2024年02月15日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包