首页 > 解决方案 > 如何在 $group 中获得原始值?

问题描述

如何在 $group 运算符中获取字段的原始值?我正在使用 $group 来获取时间范围内的最大值,我还需要在其中获取几个值。

前任:

[{
  time: "2021-01-01T10:15:32.000",
  locationId: ObjectId("6170e536f294af00124d21d7"),
  value: 36,
  lat: "21.12213",
  lng: "82.01929",
  type: "temp"
}, {
  time: "2021-01-01T10:16:32.000",
  locationId: ObjectId("6170e536f294af00124d21d7"),
  value: 23,
  lat: "21.12213",
  lng: "82.01929",
  type: "temp"
}, {
  time: "2021-01-01T10:16:32.000",
  locationId: ObjectId("6170e536f294af00124d21d7"),
  value: 26,
  lat: "21.12213",
  lng: "82.01929",
  type: "humidity"
},{
  time: "2021-01-01T10:16:32.000",
  locationId: ObjectId("6170e536f294af00124d21d7"),
  value: 12,
  lat: "21.12213",
  lng: "82.01929",
  type: "humidity"
}]

这是同一位置的数据(温度和湿度),所以 lat,lng 是相同的。我使用 $group 来获取该位置的最大温度和湿度。所以我只按天分组,不包括时间,如下所示:

[{
  $group: {
    _id: {
      time: {
        $dateToString: {
          format: "%Y-%m-%d",
          date: "$time"
        }
      },
      locId: "$locationId",
      type: "$type"
    },
    maxValue: {
      $max: "$value"
    },
    coordinate: {
      $push: {
        lat: "$lat",
        lng: "$lng"
      }
    }
  }
}]

但是如果是这样,温度和湿度不在同一个对象中,因为我type也分组了,所以我将再分组一次以time仅分组。

[{
  $group: {
    _id: {
      time: {
        $dateToString: {
          format: "%Y-%m-%d",
          date: "$time"
        }
      },
      locId: "$locationId",
      type: "$type"
    },
    maxValue: {
      $max: "$value"
    },
    coordinate: {
      $push: {
        lat: "$lat",
        lng: "$lng"
      }
    }
  }
}, {
  $group: {
    _id: "$_id.time",
    maxValues: {
      $push: {
         value: "$maxValue",
         type: "$_id.type"
      }
    },
    coordinates: {
      $last: {
        $slice: ["$coordinate", -1]
      }
    }
  }
}]

预期结果:

[{
  _id: "2021-01-01",
  maxValues: [{
    value: 36,
    type: "temp"
  }, {
    value: 26,
    type: "humidity"
  }],
  cooridinates: { lat: "21.12213" , lng: "82.01929" }
}]

响应符合我的预期,但是您可以看到,我必须将所有 lat、log 具有相同的值推送到数组中,并且在下一组中,我得到数组中的最后一个对象,因此推送坐标是多余的并且需要更多性能。这就是为什么,有时它会抛出一个错误: PlanExecutor error during aggregation :: caused by :: $push used too much memory and cannot spill to disk

所以我需要找到一个新的解决方案来优化上述查询。或者修复错误。如果您有这方面的经验,请给我一个解决方案。

标签: mongodbaggregategrouping

解决方案


最近遇到了类似的问题,在您的情况下,您可以尝试按照此处的建议使用$first来保持常量值mongo group query how to keep fields$group

{
  $group: {
    _id: {
      time: {
        $dateToString: {
          format: "%Y-%m-%d",
          date: "$time"
        }
      },
      locId: "$locationId",
      type: "$type"
    },
    maxValue: {
      $max: "$value"
    },
    lat:{$first:"$lat"},
    lng:{$first:"$lng"}

  }
}

推荐阅读