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

超大规模MongoDB气象数据集查询优化及索引问题求助

大规模MongoDB气象数据集的查询与索引问题

我正在处理一个存储了约5年逐小时气象历史数据的MongoDB集合,生产环境中集合规模超过2TB,包含约500亿条文档。开发测试阶段使用数百万条记录的样本集时,查询和索引构建都能正常运行。

简化Schema

每个文档包含GeoJSON Point类型的location字段:

{
  _id: { type: mongoose.Schema.Types.ObjectId, required: true },
  location: {
    type: {
      type: String,
      enum: ['Point'],
      required: true,
    },
    coordinates: {
      type: [Number],
      required: true,
    },
  },
  timestamp: { type: Date, required: true },
  d2m: { type: Number, required: true },
  e: { type: Number, required: true },
  ...
}

已使用索引

[
  { key: { _id: 1 }, name: '_id_' },
  { key: { location: '2dsphere' }, name: 'location_2dsphere', background: true },
  { key: { timestamp: 1 }, name: 'timestamp_1', background: true },
  { key: { 'location.coordinates': 1, timestamp: 1 }, name: 'location.coordinates_1_timestamp_1', background: true }
]

查询逻辑(开发环境)

采用两步查询实现需求,该逻辑在样本集上运行正常:

// 步骤1:查找最近坐标
const nearestStation = await WeatherDataHourlyModel.findOne({
  location: {
    $nearSphere: {
      $geometry: { type: 'Point', coordinates: [long, lat] },
      $maxDistance: 28000,
    },
  },
}).select({ location: 1 });

// 步骤2:使用精确坐标加时间范围查询
const data = await WeatherDataHourlyModel.find({
    'location.coordinates': nearestStation.location.coordinates,
    timestamp: {
      $gte: new Date(startDate),
      $lt: new Date(
        new Date(endDate).setDate(new Date(endDate).getDate() + 1)
      ),
    },
  }).sort({ timestamp: 1 });

生产环境问题

生产环境中出现以下异常:

  • 查询无限加载,始终无法返回结果;
  • 即使使用.limit(1)或.explain("executionStats")也无法完成查询;
  • 索引创建过程停滞或无响应;
  • 使用$nearSphere的查询直接报错:

执行的查询语句:

db.weatherdatas.findOne({
  location: {
    $nearSphere: {
      $geometry: { type: 'Point', coordinates: [80, 30] },
      $maxDistance: 28000,
    },
  },
})

返回错误信息:

MongoServerError[NoQueryExecutionPlans]: error processing query: ...
caused by: unable to find index for $geoNear query

但通过db.weatherdatas.getIndexes()确认location字段的2dsphere索引已存在:

db.weatherdatas.getIndexes()
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  {
    v: 2,
    key: { location: '2dsphere' },
    name: 'location_2dsphere',
    background: true,
    '2dsphereIndexVersion': 3
  },
  {
    v: 2,
    key: { timestamp: 1 },
    name: 'timestamp_1',
    background: true
  },
  {
    v: 2,
    key: { 'location.coordinates': 1, timestamp: 1 },
    name: 'location.coordinates_1_timestamp_1',
    background: true
  }
]

我已确认2dsphere索引存在、Schema及数据格式正确,但生产环境中即使简单的.limit(1)查询也耗时极久,创建{ "location.coordinates": 1, timestamp: 1 }复合索引的过程始终无法完成。现寻求以下问题的解决方案:

  • 如何优化查询以支持大规模数据?
  • 为何$nearSphere无法利用现有索引?
  • 为何查询及索引创建会停滞?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:00:07