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

如何高效查询MongoDB中的集合成员关系?

用MongoDB聚合框架一次性统计关键词所有组合的共现次数

嘿,我懂你现在反复写8种查询有多麻烦——这活儿不仅枯燥,还容易写错,而且多次请求数据库也挺浪费资源的。其实用MongoDB的聚合框架就能一次性搞定所有组合的统计,只需要一次数据库请求,效率高多了!

核心思路

我们可以分三步完成:

  1. 给每篇文章标记是否包含目标关键词(A=scotland、B=church、C=queen);
  2. 根据这三个标记分组,统计每组的文章数量;
  3. 把分组结果转换成你需要的可读格式,最后按指定顺序整理成输出数组。

具体聚合查询代码

直接运行这个聚合命令,就能得到所有组合的统计结果:

db.article_list.aggregate([
  // 第一步:标记每篇文章是否包含三个关键词
  {
    $addFields: {
      hasA: { $in: ["scotland", "$keywords"] },
      hasB: { $in: ["church", "$keywords"] },
      hasC: { $in: ["queen", "$keywords"] }
    }
  },
  // 第二步:按三个标记分组,统计每组的文档数
  {
    $group: {
      _id: { hasA: "$hasA", hasB: "$hasB", hasC: "$hasC" },
      count: { $sum: 1 }
    }
  },
  // 第三步:将分组的布尔标记转换成易读的组合名称(可选,但更直观)
  {
    $project: {
      _id: 0,
      combination: {
        $switch: {
          branches: [
            { case: { $and: ["$_id.hasA", "$_id.hasB", "$_id.hasC"] }, then: "A & B & C" },
            { case: { $and: ["$_id.hasA", "$_id.hasB", { $not: "$_id.hasC" }] }, then: "A & B (无C)" },
            { case: { $and: ["$_id.hasA", { $not: "$_id.hasB" }, "$_id.hasC"] }, then: "A & C (无B)" },
            { case: { $and: ["$_id.hasA", { $not: "$_id.hasB" }, { $not: "$_id.hasC" }] }, then: "仅存在A" },
            { case: { $and: [{ $not: "$_id.hasA" }, "$_id.hasB", "$_id.hasC"] }, then: "B & C (无A)" },
            { case: { $and: [{ $not: "$_id.hasA" }, "$_id.hasB", { $not: "$_id.hasC" }] }, then: "仅存在B" },
            { case: { $and: [{ $not: "$_id.hasA" }, { $not: "$_id.hasB" }, "$_id.hasC"] }, then: "仅存在C" },
            { case: { $and: [{ $not: "$_id.hasA" }, { $not: "$_id.hasB" }, { $not: "$_id.hasC" }] }, then: "均不存在" }
          ]
        }
      },
      count: 1
    }
  }
])

聚合结果示例

这个查询会返回类似这样的结果(包含所有8种组合):

[
  { "combination": "A & B & C", "count": 10 },
  { "combination": "A & B (无C)", "count": 20 },
  { "combination": "A & C (无B)", "count": 20 },
  { "combination": "仅存在A", "count": 5 },
  { "combination": "B & C (无A)", "count": 5 },
  { "combination": "仅存在B", "count": 10 },
  { "combination": "仅存在C", "count": 20 },
  { "combination": "均不存在", "count": 10 }
]

转换成指定顺序的输出数组

如果需要把结果转换成你要求的逗号分隔数组格式,可以在客户端代码里做简单整理(以JavaScript为例):

// 定义你需要的输出顺序
const desiredOrder = [
  "A & B & C",
  "A & B (无C)",
  "A & C (无B)",
  "仅存在A",
  "B & C (无A)",
  "仅存在B",
  "仅存在C",
  "均不存在"
];

// 假设聚合查询的结果存在results变量中
const resultMap = new Map(results.map(item => [item.combination, item.count]));
const outputArray = desiredOrder.map(key => resultMap.get(key) || 0);

// 输出最终结果
console.log(outputArray.join(', ')); // 输出: 10,20,20,5,5,10,20,10

为什么这个方案更好?

  • 只需要一次数据库请求,减少了网络开销和数据库负载;
  • 逻辑集中在聚合管道里,比写8个重复的count查询更易维护;
  • 性能更优,尤其是当数据量很大时,聚合框架的处理效率远高于多次单独查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:28:54