时间旅行 #

一、时间旅行概述 #

1.1 什么是时间旅行 #

text
时间旅行功能:
├── 查询历史数据状态
├── 访问任意时间点的数据
├── 追踪数据变更历史
├── 支持数据恢复
└── 审计和合规

1.2 历史数据保留 #

text
历史数据配置:
├── history_days
│   └── 集合级别配置
├── 默认30天
├── 可设置为0(不保留)
└── 可设置更长(如90天)

二、历史查询 #

2.1 获取历史时间点数据 #

javascript
// 获取特定时间点的文档
Get(
  Ref(Collection("users"), "user_001"),
  Time("2024-01-01T00:00:00Z")
)

// 获取昨天的数据状态
Get(
  Ref(Collection("products"), "prod_001"),
  TimeSubtract(Now(), 1, "day")
)

2.2 查询历史事件 #

javascript
// 获取文档的所有变更事件
Paginate(
  Events(Ref(Collection("users"), "user_001"))
)

// 返回格式
{
  data: [
    {
      ts: 1704067200000000,
      action: "create",
      document: Ref(Collection("users"), "user_001"),
      instance: Ref(Collection("users"), "user_001")
    },
    {
      ts: 1704153600000000,
      action: "update",
      document: Ref(Collection("users"), "user_001"),
      instance: Ref(Collection("users"), "user_001")
    }
  ]
}

2.3 时间范围查询 #

javascript
// 查询时间范围内的变更
Paginate(
  Events(Ref(Collection("users"), "user_001")),
  {
    start: Time("2024-01-01T00:00:00Z"),
    end: Time("2024-01-31T23:59:59Z")
  }
)

三、历史数据分析 #

3.1 追踪数据变更 #

javascript
// 获取文档变更历史
Let(
  {
    events: Select(
      ["data"],
      Paginate(
        Events(Ref(Collection("users"), "user_001")),
        { size: 100 }
      )
    )
  },
  Map(
    Var("events"),
    Lambda("event",
      Let(
        {
          ts: Select(["ts"], Var("event")),
          action: Select(["action"], Var("event")),
          doc: Get(
            Ref(Collection("users"), "user_001"),
            Var("ts")
          )
        },
        {
          timestamp: Var("ts"),
          action: Var("action"),
          data: Select(["data"], Var("doc"))
        }
      )
    )
  )
)

3.2 比较历史版本 #

javascript
// 比较两个时间点的数据差异
Let(
  {
    docNow: Get(Ref(Collection("users"), "user_001")),
    docYesterday: Get(
      Ref(Collection("users"), "user_001"),
      TimeSubtract(Now(), 1, "day")
    )
  },
  {
    current: Select(["data"], Var("docNow")),
    yesterday: Select(["data"], Var("docYesterday")),
    changes: {
      name: {
        from: Select(["data", "name"], Var("docYesterday")),
        to: Select(["data", "name"], Var("docNow"))
      },
      email: {
        from: Select(["data", "email"], Var("docYesterday")),
        to: Select(["data", "email"], Var("docNow"))
      }
    }
  }
)

3.3 变更统计 #

javascript
// 统计变更次数
Let(
  {
    events: Select(
      ["data"],
      Paginate(
        Events(Ref(Collection("users"), "user_001"))
      )
    )
  },
  {
    totalChanges: Count(Var("events")),
    creates: Count(
      Filter(
        Var("events"),
        Lambda("e", Equals(Select(["action"], Var("e")), "create"))
      )
    ),
    updates: Count(
      Filter(
        Var("events"),
        Lambda("e", Equals(Select(["action"], Var("e")), "update"))
      )
    ),
    deletes: Count(
      Filter(
        Var("events"),
        Lambda("e", Equals(Select(["action"], Var("e")), "delete"))
      )
    )
  }
)

四、数据恢复 #

4.1 恢复历史版本 #

javascript
// 恢复到特定时间点
Let(
  {
    targetTime: Time("2024-01-15T00:00:00Z"),
    historicalDoc: Get(
      Ref(Collection("products"), "prod_001"),
      Var("targetTime")
    )
  },
  Update(
    Ref(Collection("products"), "prod_001"),
    {
      data: Select(["data"], Var("historicalDoc"))
    }
  )
)

4.2 批量恢复 #

javascript
// 批量恢复多个文档
Let(
  {
    targetTime: Time("2024-01-01T00:00:00Z"),
    refs: [
      Ref(Collection("products"), "prod_001"),
      Ref(Collection("products"), "prod_002"),
      Ref(Collection("products"), "prod_003")
    ]
  },
  Map(
    Var("refs"),
    Lambda("ref",
      Let(
        {
          historicalDoc: Get(Var("ref"), Var("targetTime"))
        },
        Update(Var("ref"), {
          data: Select(["data"], Var("historicalDoc"))
        })
      )
    )
  )
)

4.3 撤销删除 #

javascript
// 恢复已删除的文档
Let(
  {
    ref: Ref(Collection("users"), "deleted_user_001"),
    events: Select(
      ["data"],
      Paginate(Events(Var("ref")))
    ),
    lastValidEvent: Last(
      Filter(
        Var("events"),
        Lambda("e", Not(Equals(Select(["action"], Var("e")), "delete")))
      )
    ),
    lastValidTime: Select(["ts"], Var("lastValidEvent"))
  },
  Let(
    {
      lastValidDoc: Get(Var("ref"), Var("lastValidTime"))
    },
    Create(Var("ref"), {
      data: Select(["data"], Var("lastValidDoc"))
    })
  )
)

五、审计日志 #

5.1 创建审计系统 #

javascript
// 使用事件作为审计日志
Let(
  {
    userRef: Ref(Collection("users"), "user_001"),
    events: Select(
      ["data"],
      Paginate(
        Events(Var("userRef")),
        { size: 100 }
      )
    )
  },
  Map(
    Var("events"),
    Lambda("event",
      {
        timestamp: Select(["ts"], Var("event")),
        action: Select(["action"], Var("event")),
        user: Var("userRef"),
        details: If(
          Equals(Select(["action"], Var("event")), "update"),
          Let(
            {
              doc: Get(Var("userRef"), Select(["ts"], Var("event")))
            },
            Select(["data"], Var("doc"))
          ),
          null
        )
      }
    )
  )
)

5.2 变更追踪 #

javascript
// 追踪字段变更
CreateFunction({
  name: "track_field_changes",
  body: Query(
    Lambda(["ref", "fieldName"],
      Let(
        {
          events: Select(
            ["data"],
            Paginate(Events(Var("ref")))
          )
        },
        Map(
          Var("events"),
          Lambda("event",
            Let(
              {
                ts: Select(["ts"], Var("event")),
                doc: Get(Var("ref"), Var("ts")),
                fieldValue: Select(["data", fieldName], Var("doc"), null)
              },
              {
                timestamp: Var("ts"),
                action: Select(["action"], Var("event")),
                fieldValue: Var("fieldValue")
              }
            )
          )
        )
      )
    )
  )
})

六、时间范围分析 #

6.1 时间段对比 #

javascript
// 对比不同时间段的数据
Let(
  {
    ref: Ref(Collection("sales"), "daily_001"),
    week1Start: Time("2024-01-01T00:00:00Z"),
    week1End: Time("2024-01-07T23:59:59Z"),
    week2Start: Time("2024-01-08T00:00:00Z"),
    week2End: Time("2024-01-14T23:59:59Z")
  },
  {
    week1: Get(Var("ref"), Var("week1End")),
    week2: Get(Var("ref"), Var("week2End"))
  }
)

6.2 趋势分析 #

javascript
// 分析数据变化趋势
Let(
  {
    ref: Ref(Collection("metrics"), "daily_active_users"),
    days: Map(
      [0, 1, 2, 3, 4, 5, 6],
      Lambda("i",
        TimeSubtract(Now(), Var("i"), "day")
      )
    )
  },
  Map(
    Var("days"),
    Lambda("day",
      Let(
        {
          doc: Get(Var("ref"), Var("day"))
        },
        {
          date: Var("day"),
          value: Select(["data", "value"], Var("doc"))
        }
      )
    )
  )
)

七、配置历史保留 #

7.1 设置保留天数 #

javascript
// 创建集合时设置
CreateCollection({
  name: "important_data",
  history_days: 90  // 保留90天历史
})

// 更新现有集合
Update(Collection("users"), {
  history_days: 60
})

// 禁用历史
Update(Collection("logs"), {
  history_days: 0
})

7.2 保留策略 #

text
保留策略建议:
├── 关键业务数据:90天或更长
├── 用户数据:30-60天
├── 日志数据:7-30天
├── 临时数据:0天(不保留)
└── 考虑存储成本

八、实际应用示例 #

8.1 价格历史追踪 #

javascript
// 产品价格历史
CreateFunction({
  name: "get_price_history",
  body: Query(
    Lambda(["productId", "startDate", "endDate"],
      Let(
        {
          ref: Ref(Collection("products"), Var("productId")),
          events: Select(
            ["data"],
            Paginate(
              Events(Var("ref")),
              {
                start: Var("startDate"),
                end: Var("endDate")
              }
            )
          )
        },
        Map(
          Var("events"),
          Lambda("event",
            Let(
              {
                ts: Select(["ts"], Var("event")),
                doc: Get(Var("ref"), Var("ts"))
              },
              {
                timestamp: Var("ts"),
                price: Select(["data", "price"], Var("doc")),
                action: Select(["action"], Var("event"))
              }
            )
          )
        )
      )
    )
  )
})

8.2 订单状态历史 #

javascript
// 订单状态变更历史
CreateFunction({
  name: "get_order_status_history",
  body: Query(
    Lambda("orderId",
      Let(
        {
          ref: Ref(Collection("orders"), Var("orderId")),
          events: Select(
            ["data"],
            Paginate(Events(Var("ref")))
          )
        },
        Map(
          Var("events"),
          Lambda("event",
            Let(
              {
                ts: Select(["ts"], Var("event")),
                doc: Get(Var("ref"), Var("ts"))
              },
              {
                timestamp: Var("ts"),
                status: Select(["data", "status"], Var("doc")),
                action: Select(["action"], Var("event"))
              }
            )
          )
        )
      )
    )
  )
})

8.3 数据快照 #

javascript
// 创建数据快照
CreateFunction({
  name: "create_snapshot",
  body: Query(
    Lambda("collectionName",
      Let(
        {
          snapshotTime: Now(),
          docs: Map(
            Paginate(Documents(Collection(Var("collectionName")))),
            Lambda("ref", Get(Var("ref")))
          )
        },
        Create(Collection("snapshots"), {
          data: {
            collection: Var("collectionName"),
            timestamp: Var("snapshotTime"),
            data: Var("docs")
          }
        })
      )
    )
  )
})

九、性能考虑 #

9.1 历史查询性能 #

text
性能建议:
├── 历史查询比当前查询慢
├── 限制时间范围
├── 使用适当的history_days
├── 避免频繁历史查询
└── 考虑缓存结果

9.2 存储成本 #

text
存储考虑:
├── 历史数据占用存储空间
├── 更长的history_days = 更多存储
├── 平衡需求和成本
└── 定期评估保留策略

十、总结 #

时间旅行要点:

功能 说明
Get with time 获取历史版本
Events 查询变更事件
history_days 历史保留天数
数据恢复 恢复历史版本
审计追踪 变更历史记录

下一步,让我们学习备份与恢复!

最后更新:2026-03-27