首页 > 解决方案 > Firestore 数据库时间序列数据建模

问题描述

我想将时间序列数据存储在 Firestore 数据库中,以便通过利用 Firebase 过滤功能和最佳实践来尽可能有效地检索和更新它。

就将存储的实际数据而言,每日数据点将具有相应的单个数值,例如 1580651062 - 45。

以下是需要遵循的初始 Firestore 结构的示例:

/exampleData/userId/accountId/ <-- 从这里开始我想存储时间序列数据。

示例 json 结构:

"exampleData": {
    "123": { // accountId
        "1546300800": { // 'yearKey' - 2019/01/01/00:00:000
            "1548979200": [ // 'monthKey' - 2019/02/01/00:00:000, that contains daily data of 2019/02/x/xx:xx:xxx
                {
                    "timestamp": 1549070411,
                    "value": 20
                },
                {
                    "timestamp": 1549077675,
                    "value": 10
                }
            ],
            "1551398400": [ // 'monthKey' - 2019/03/01/00:00:000, that contains daily data of 2019/03/x/xx:xx:xxx
                {
                    "timestamp": 1551669675,
                    "value": 22
                }
            ]
        },
        "1577836800": { // 'yearKey' - 2020/01/01/00:00:000
            "1577836800": [ // 'monthKey' - 2019/02/01/00:00:000, that contains daily data of 2019/02/x/xx:xx:xxx
                {
                    "timestamp": 1580651062,
                    "value": 33
                }
            ]
        }
    }
}

基于上述,我有以下作为潜在的解决方案:

/exampleData
    /userId(Document) 
        /797499614(Collection)
            /randomDocId
                /yearlyData(Collection)
                    /randomDocId
                        /monthlyData(Collection)
                            /randomDocId
                                /dailyData(Collection)
                                    /randomDocId

其中yearlyData 集合包含yearKey 和相应的monthlyData 集合,然后包含monthKey 和相应的dailyData 集合,该集合包含每个数据点的单独文档,其中dayKey 和一个值。理论上,具有后一种结构应该允许执行粒度过滤并允许在处理之前最小化下载到客户端的数据量,例如

db.collection("exampleData")
  .doc("userId")
  .collection("accountId")
  .collection("yearlyData")
  .where("yearKey", ">=", 30)
  .where("yearKey", "<=", 40)
  .getMonthlyDataCollections()
  .where("monthKey", ">=", 20)
  .where("monthKey", "<=", 30)
  .getDailyDataCollections()
  .where("dayKey", ">=", 5)
  .where("monthKey", "<=", 10)
  .get()
  .then(data => {
       process(data);
  });

有没有比上述解决方案更好的方法来实现要求?

如果我要采用上述解决方案,那么上述 firestore 查询中“.getMonthlyDataCollections()”和“.getDailyDataCollections()”的示例实现是什么?意思是,firestore api 是否提供了一种类似“加入”的选项来实际实现上述目标,而无需将所有数据拉到客户端?

谢谢。

标签: javascriptfirebasegoogle-cloud-firestore

解决方案


firestore api 是否提供了一种类似“加入”的选项来实际实现上述目标,而无需将所有数据拉到客户端?

Firestore 查询不提供任何类型的类似 SQL 的连接。每个查询一次只能考虑一个集合。唯一的例外是集合组查询,您可以在其中查询具有相同名称的所有集合。

因此,在 Firestore(和所有 NoSQL 类型的数据库)中,在多个集合之间复制数据是很常见的,以满足更轻松的查询。这称为“非规范化”。


推荐阅读