Firestore 为 noSQL 和 Flutter 复制 SQL Join

Jak*_*son 5 nosql dart firebase flutter google-cloud-firestore

我意识到与 NoSql 文档数据库(例如 FireStore)复制连接存在很多问题,但是我无法找到使用 Dart/Flutter 和 FireStore 的彻底解决方案。

我做了一些研究,我觉得在下面的示例中,我将寻找“多对多”关系(如果这是错误的,请纠正我),因为将来可能需要查看所有配置文件以及所有连接。

在 firebase 中,我有两个根级别集合(配置文件和连接):

profile
    > documentKey(Auto Generated)
         > name = "John Smith"
         > uid = "xyc4567"

    > documentKey(Auto Generated)
         > name = "Jane Doe"
         > uid = "abc1234"

    > documentKey(Auto Generated)
         > name = "Kate Dee"
         > uid = "efg8910"



connection
    > documentKey(Auto Generated)
         > type = "friend"
         > profileuid = "abc1234"
         > uid = "xyc4567"

    > documentKey(Auto Generated)
         > type = "family"
         > profileuid = "abc1234"
         > uid = "efg8910"
Run Code Online (Sandbox Code Playgroud)

对于此示例,当用户 John Smith(uid:xyc4567)连接到 Jane Doe(uid:abc1234)和 Kate Dee(uid:efg8910)时,假设为他创建了“连接”文档。

这是我想要复制的关系 SQL,以显示 John Smith 已连接的配置文件列表:

Select * FROM profile, connection 
WHERE profile.uid = connection.profileuid 
AND profile.uid = "xyc4567"
Run Code Online (Sandbox Code Playgroud)

在 flutter 我的 flutter 应用程序中,我有一个 fireStore 查询起点:

stream: Firestore.instance.collection('profile')
.where('uid', isEqualTo: "xyc4567").snapshots(),
Run Code Online (Sandbox Code Playgroud)

显然它只从一个集合中返回。如何以多对多关系加入集合?

Ale*_*amo 7

JOIN不幸的是, Cloud Firestore 或其他 NoSQL 数据库中都没有该子句。在 Firestore 中,查询很浅。这意味着它们仅从运行查询的集合中获取项目。无法在单个查询中从两个顶级集合中获取文档。Firestore 不支持一次性跨不同集合进行查询。单个查询只能使用单个集合中文档的属性。

所以我能想到的最简单的解决方案是查询数据库以uid从集合中获取用户的profileconnection获得该 ID 后,进行另一个数据库调用(在回调内),并使用以下查询从集合中获取所需的相应数据:

stream: Firestore.instance.collection('connection').where('uid', isEqualTo: "xyc4567").snapshots(),
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是创建一个在每个用户下命名的子集合,并在其下connection添加所有对象。connection这种做法称为denormalizationFirebase 的常见做法。如果您是 NoQSL 数据库的新手,我建议您观看此视频,非规范化在 Firebase 数据库中是正常的,以便更好地理解。它适用于 Firebase 实时数据库,但相同的规则适用于 Cloud Firestore。

另外,当您复制数据时,需要记住一件事。就像添加数据一样,您也需要维护它。换句话说,如果你想更新/删除一个项目,你需要在它存在的每个地方进行操作。