【问题标题】:Firestore database time-series data modellingFirestore 数据库时间序列数据建模
【发布时间】:2021-01-19 19:51:52
【问题描述】:

我希望将时间序列数据存储在 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 是否提供了一种类似“加入”的选项来实际实现上述目标,而无需将所有数据拉到客户端?

谢谢。

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

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

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

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

    【讨论】: