You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB查询:按枚举状态优先级随机选取3条文档的实现方法

按状态优先级随机选取MongoDB文档的实现方案

需求是随机选取3条文档,但需严格遵循NEW > IN_PROGRESS > PAUSED的状态优先级:优先从NEW状态中选取,若NEW数量不足3条,再从IN_PROGRESS中补充,仍不足则从PAUSED中补全。

原代码直接使用sample阶段无法实现优先级逻辑,需通过聚合管道的多阶段处理来满足需求,以下是修改后的Kotlin实现:

mongoTemplate.aggregate<Book, Book>(
    newAggregation(
        // 筛选目标状态的文档
        match(where("status").`in`(BookStatus.allToBeRead)),
        // 按状态分桶,每个桶内随机采样足够数量的文档
        facet(
            AggregationOperation { context ->
                Document("NEW", listOf(
                    Document("\$match", Document("status", BookStatus.NEW.name)),
                    Document("\$sample", Document("size", 3))
                ))
            },
            AggregationOperation { context ->
                Document("IN_PROGRESS", listOf(
                    Document("\$match", Document("status", BookStatus.IN_PROGRESS.name)),
                    Document("\$sample", Document("size", 3))
                ))
            },
            AggregationOperation { context ->
                Document("PAUSED", listOf(
                    Document("\$match", Document("status", BookStatus.PAUSED.name)),
                    Document("\$sample", Document("size", 3))
                ))
            }
        ),
        // 将分桶结果展开为单个文档,允许空值避免无对应状态时中断
        unwind("\$NEW"),
        unwind("\$IN_PROGRESS", true),
        unwind("\$PAUSED", true),
        // 合并所有候选文档,并标记优先级
        project()
            .and("NEW").as("doc").whenNull("IN_PROGRESS").whenNull("PAUSED")
            .and(0).as("priority").when(where("NEW").exists(true))
            .and(1).as("priority").when(where("IN_PROGRESS").exists(true))
            .and(2).as("priority").when(where("PAUSED").exists(true)),
        // 按优先级升序排序,保证高优先级文档在前
        sort(Sort.by(Sort.Order.asc("priority"))),
        // 取前3条文档
        limit(3),
        // 恢复原始文档结构
        replaceRoot("\$doc")
    )
)

代码逻辑说明

  1. 分桶采样:通过facet将三个状态的文档分别处理,每个状态采样最多3条,确保有足够的候选文档。
  2. 合并与优先级标记:将分桶结果展开后,合并为统一的文档流,并为不同状态标记优先级(NEW=0,IN_PROGRESS=1,PAUSED=2)。
  3. 排序与截取:按优先级升序排序,确保高优先级文档排在前面,最后截取前3条即可满足需求。

示例验证

  • 示例1:当NEW状态文档≥3条时,结果全部为随机选取的NEW文档。
  • 示例2:当NEW只有2条时,会从IN_PROGRESS中随机补1条,最终结果为2条NEW+1条IN_PROGRESS。

内容的提问来源于stack exchange,提问作者inconnu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:47:24