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

如何在MongoDB的$or查询中合并每个条件返回的首条记录

MongoDB实现多条件子查询各取首条并合并结果

错误原因

你原来的查询语法错误是因为**$limit是游标方法或聚合阶段操作符**,不能放在$or的筛选条件文档里,它不属于查询匹配条件的一部分。

正确解决方案

以下两种方法都能实现你要的需求:每个过滤条件取首条记录,最终合并所有结果。

方法一:使用$facet聚合(推荐,并行处理)

通过$facet并行处理多个子查询,每个子查询匹配条件、排序取最新记录、限制1条,最后合并结果:

db["mydata"].aggregate([
  {
    $facet: {
      // 第一个子查询:device1+reader x+温度
      temp_x: [
        { $match: {
          "device": "device1",
          "reader": "x", 
          "measurement": "temperature", 
          "SourceTimeUtc": { "$lte": ISODate("2023-01-11T06:07:47.280Z") }
        }},
        { $sort: { SourceTimeUtc: -1 } }, // 按时间倒序,确保取符合条件的最新记录
        { $limit: 1 }
      ],
      // 第二个子查询:device1+reader y+温度
      temp_y: [
        { $match: {
          "device": "device1",
          "reader": "y", 
          "measurement": "temperature", 
          "SourceTimeUtc": { "$lte": ISODate("2023-01-11T06:07:47.280Z") }
        }},
        { $sort: { SourceTimeUtc: -1 } },
        { $limit: 1 }
      ],
      // 第三个子查询:device1+reader x+湿度
      humidity_x: [
        { $match: {
          "device": "device1",
          "reader": "x", 
          "measurement": "humidity", 
          "SourceTimeUtc": { "$lte": ISODate("2023-01-11T06:07:47.280Z") }
        }},
        { $sort: { SourceTimeUtc: -1 } },
        { $limit: 1 }
      ]
    }
  },
  // 合并三个子查询的结果数组
  { $project: {
    results: { $concatArrays: ["$temp_x", "$temp_y", "$humidity_x"] }
  }},
  // 展开结果数组为单个文档
  { $unwind: "$results" },
  // 将每个结果文档作为根文档返回
  { $replaceRoot: { newRoot: "$results" } }
])

方法二:使用$unionWith合并子查询

依次执行三个独立的子查询,每个子查询取首条记录,再通过$unionWith合并结果集:

db["mydata"].aggregate([
  // 第一个子查询
  { $match: {
    "device": "device1",
    "reader": "x", 
    "measurement": "temperature", 
    "SourceTimeUtc": { "$lte": ISODate("2023-01-11T06:07:47.280Z") }
  }},
  { $sort: { SourceTimeUtc: -1 } },
  { $limit: 1 },
  // 合并第二个子查询结果
  { $unionWith: {
    coll: "mydata",
    pipeline: [
      { $match: {
        "device": "device1",
        "reader": "y", 
        "measurement": "temperature", 
        "SourceTimeUtc": { "$lte": ISODate("2023-01-11T06:07:47.280Z") }
      }},
      { $sort: { SourceTimeUtc: -1 } },
      { $limit: 1 }
    ]
  }},
  // 合并第三个子查询结果
  { $unionWith: {
    coll: "mydata",
    pipeline: [
      { $match: {
        "device": "device1",
        "reader": "x", 
        "measurement": "humidity", 
        "SourceTimeUtc": { "$lte": ISODate("2023-01-11T06:07:47.280Z") }
      }},
      { $sort: { SourceTimeUtc: -1 } },
      { $limit: 1 }
    ]
  }}
])

注意事项

  • 一定要添加$sort: { SourceTimeUtc: -1 }:如果不指定排序,MongoDB返回的第一条记录是不确定的(依赖存储顺序),倒序排序能确保你拿到的是符合时间条件的最新记录。
  • 如果你的需求是取最早的记录,把排序改为{ SourceTimeUtc: 1 }即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:30:45