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

Mongo聚合操作中带限制条件的去重方法

嘿,针对你的问题——在MongoDB聚合操作里结合筛选条件实现去重,我结合你提供的AIS船舶数据场景,整理了几种实用方案:

方案一:先过滤条件,再分组去重(性能优先推荐)

先通过$match把符合限制条件的数据筛选出来,再用$group按目标字段(比如你的场景里的MMSI)聚合去重,同时保留你需要的关联字段。

举个例子:假设你要筛选STATUS='0'、时间在2013年12月内的数据,然后按MMSI去重,保留每个船舶最新的那条定位记录:

db.yourCollection.aggregate([
  // 第一步:先过滤出符合要求的数据
  {
    $match: {
      "properties.STATUS": "0",
      "properties.TIMESTAMP": {
        $gte: "2013-12-01 00:00:00.000",
        $lte: "2013-12-31 23:59:59.999"
      }
    }
  },
  // 第二步:按时间倒序排序,确保最新的记录排在前面
  {
    $sort: { "properties.TIMESTAMP": -1 }
  },
  // 第三步:按MMSI分组去重,保留最新记录的字段
  {
    $group: {
      _id: "$properties.MMSI", // 按MMSI作为分组键实现去重
      latestTimestamp: { $max: "$properties.TIMESTAMP" },
      latestGeometry: { $first: "$geometry" },
      latestPosId: { $first: "$properties.POS_ID" },
      originalDocId: { $first: "$_id" }
    }
  },
  // 可选:把分组后的结果还原成类似原文档的结构
  {
    $project: {
      _id: "$originalDocId",
      type: "Feature",
      geometry: "$latestGeometry",
      properties: {
        MMSI: "$_id",
        TIMESTAMP: "$latestTimestamp",
        POS_ID: "$latestPosId",
        STATUS: "0"
      }
    }
  }
])

方案二:先分组去重,再过滤结果

如果你的限制条件是针对分组后的结果(比如只保留最新定位时间在某个时段的船舶),可以先完成分组去重,再用$match过滤:

db.yourCollection.aggregate([
  {
    $sort: { "properties.TIMESTAMP": -1 }
  },
  {
    $group: {
      _id: "$properties.MMSI",
      latestTimestamp: { $max: "$properties.TIMESTAMP" },
      latestGeometry: { $first: "$geometry" },
      status: { $first: "$properties.STATUS" }
    }
  },
  // 分组后再过滤符合条件的结果
  {
    $match: {
      status: "0",
      latestTimestamp: { $gte: "2013-12-31 18:00:00.000" }
    }
  }
])

方案三:快速获取去重字段集合

如果你只需要拿到某个字段的去重列表(比如所有符合条件的MMSI),可以用$addToSet:

db.yourCollection.aggregate([
  {
    $match: { "properties.STATUS": "0" }
  },
  {
    $group: {
      _id: null,
      uniqueMMSIs: { $addToSet: "$properties.MMSI" }
    }
  }
])

几个关键提醒

  • 性能优化:一定要把$match放在聚合管道的最前面,先过滤掉无关数据,能大幅减少后续分组的计算量。
  • 排序必要性:如果需要保留特定顺序的记录(比如最新/最早),必须在分组前做排序,否则$first/$last的结果是随机的。
  • 结构还原:分组后的结果结构会变化,用$project或$replaceRoot可以把输出调整成你需要的格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:26:47