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

MongoDB以Unix时间戳为键的历史数据如何查询指定日期间记录

商品历史时间区间数据查询方案

现有存储结构下的临时查询方案

你当前的存储逻辑是将Unix时间戳作为字段名存储,MongoDB没有直接支持按字段名范围查询的原生语法,可通过聚合操作实现需求:

  1. 先将指定的日期A、日期B转换为和你存储精度一致的Unix时间戳(示例中是毫秒级)
  2. 执行如下聚合查询语句:
// 替换为你自己的起止时间戳
const startTs = 1634553370000; 
const endTs = 1634558360000;

db.你的集合名称.aggregate([
  // 可选:指定要查询的商品ID,减少扫描范围
  { $match: { collectibleId: "bc50774d-b923-4a5c-8e5d-f25608e1e80e" } },
  // 将文档所有键值对转换为数组格式
  { $objectToArray: "$$ROOT" },
  // 过滤出时间范围内的字段,排除固定元字段
  {
    $project: {
      collectibleId: 1,
      targetHistory: {
        $filter: {
          input: "$v",
          as: "field",
          cond: {
            $and: [
              { $gte: [{ $toLong: "$$field.k" }, startTs] },
              { $lte: [{ $toLong: "$$field.k" }, endTs] },
              { $nin: ["$$field.k", ["_id", "collectibleId"]] }
            ]
          }
        }
      }
    }
  },
  // 可选:将过滤后的结果转回对象格式
  {
    $replaceRoot: {
      newRoot: {
        $arrayToObject: {
          $concatArrays: [
            [{ k: "collectibleId", v: "$collectibleId" }],
            "$targetHistory"
          ]
        }
      }
    }
  }
])

注意:该方案需要遍历单文档内的所有字段做格式转换,若单文档内时间戳字段过万,查询性能会明显下降,仅适合临时查询使用。

长期存储优化方案

将时间戳作为字段名属于MongoDB的设计反模式,会大幅提升查询、统计的复杂度,建议调整为嵌套数组的存储结构,优化后结构示例如下:

{
    "_id" : ObjectId("616d4e1c1e7edf6e9bcdd668"),
    "collectibleId" : "bc50774d-b923-4a5c-8e5d-f25608e1e80e",
    "history" : [
        {
            "timestamp": 1634553373797,
            "storePrice" : "39.99"
        },
        {
            "timestamp": 1634554743600,
            "storePrice" : "39.99"
        },
        {
            "timestamp": 1634558354739,
            "storePrice" : "39.99"
        }
    ]
}

调整结构后,时间区间查询的复杂度和性能都会大幅优化,还可以给history.timestamp加索引进一步提效,对应查询语句如下:

const startTs = 1634553370000;
const endTs = 1634558360000;

db.你的集合名称.aggregate([
  { $match: { collectibleId: "bc50774d-b923-4a5c-8e5d-f25608e1e80e" } },
  {
    $project: {
      collectibleId: 1,
      history: {
        $filter: {
          input: "$history",
          as: "record",
          cond: {
            $and: [
              { $gte: ["$$record.timestamp", startTs] },
              { $lte: ["$$record.timestamp", endTs] }
            ]
          }
        }
      }
    }
  }
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:57:03