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

MongoDB单查询实现C1过滤结果关联C2及多条件计数

没问题,这需求用MongoDB的聚合管道就能搞定单条查询实现,我给你拆解下步骤,再附上Java Spring里的代码实现~

原生MongoDB聚合查询语句

先看直接在MongoDB shell里能跑的原生查询,逻辑清晰易懂:

db.C1.aggregate([
  // 第一步:筛选C1中special为foo的记录,减少后续处理量
  {
    $match: { "special": "foo" }
  },
  // 第二步:关联C2集合,把匹配的记录存入c2字段
  {
    $lookup: {
      from: "C2",
      localField: "related",
      foreignField: "name",
      as: "c2"
    }
  },
  // 第三步:计算三个计数字段
  {
    $addFields: {
      lowCount: {
        $size: {
          $filter: {
            input: "$c2",
            cond: { $lte: ["$$this.total", 100] }
          }
        }
      },
      midCount: {
        $size: {
          $filter: {
            input: "$c2",
            cond: { $and: [{ $gt: ["$$this.total", 100] }, { $lte: ["$$this.total", 500] }] }
          }
        }
      },
      highCount: {
        $size: {
          $filter: {
            input: "$c2",
            cond: { $gt: ["$$this.total", 500] }
          }
        }
      }
    }
  }
])

各阶段说明

  • $match:先把符合条件的C1记录筛选出来,避免后续处理无关数据,提升性能
  • $lookup:相当于SQL的左关联,把C2中name与当前C1记录related匹配的所有结果,打包成数组存入c2字段(兼容一对一/一对多的匹配场景)
  • $addFields:通过$filter从c2数组里捞符合计数条件的元素,再用$size获取数组长度,得到对应的统计数
Java Spring框架实现(基于MongoTemplate)

如果用Spring Data MongoDB的MongoTemplate,可以这样写代码,完全对应上面的聚合逻辑:

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.query.Criteria;

import java.util.List;

// 假设你的C1实体类是C1Document,记得要包含c2、lowCount、midCount、highCount字段
public List<C1Document> getFilteredDataWithCounts(MongoTemplate mongoTemplate) {
    // 构建$match阶段
    AggregationOperation matchStage = Aggregation.match(Criteria.where("special").is("foo"));

    // 构建$lookup阶段
    LookupOperation lookupStage = LookupOperation.newLookup()
            .from("C2")
            .localField("related")
            .foreignField("name")
            .as("c2");

    // 构建$addFields阶段,计算三个计数字段
    AggregationOperation addFieldsStage = Aggregation.addFields()
            .addFieldWithValue("lowCount", Aggregation.size(Aggregation.filter("c2", "item",
                    Criteria.where("$$item.total").lte(100).getCriteriaObject())))
            .addFieldWithValue("midCount", Aggregation.size(Aggregation.filter("c2", "item",
                    Criteria.where("$$item.total").gt(100).lte(500).getCriteriaObject())))
            .addFieldWithValue("highCount", Aggregation.size(Aggregation.filter("c2", "item",
                    Criteria.where("$$item.total").gt(500).getCriteriaObject())))
            .build();

    // 组装并执行聚合查询
    Aggregation aggregation = Aggregation.newAggregation(matchStage, lookupStage, addFieldsStage);
    return mongoTemplate.aggregate(aggregation, "C1", C1Document.class).getMappedResults();
}

注意事项

  • 你的C1Document实体类需要添加对应字段:比如用@Field("c2") private List<C2Document> c2;来映射关联结果,private Integer lowCount;等字段来接收统计值
  • 如果C2也有实体类C2Document,Spring会自动完成数据映射,不用手动处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:57:48