如何在Firestore和Android中选择位置?

时间:2018-11-01 10:39:47

标签: firebase database-design google-cloud-firestore

我是Cloud Firestore的新手,请帮助我。我正在为青少年创建一个应用程序,我想在其中显示每个城市非常好的位置的列表。我还希望每个用户都可以将任何位置保存到收藏夹区域,以便他或她可以将该位置列表显示给他或她的朋友。

  

我的实际数据:

  • db->用户(所有用户)
  • db->位置(所有位置)
  

我的问题:

我想找到一种将用户的位置设置为收藏夹的方法。我正在考虑在每个用户下创建一个新部分,以保存每个喜欢的位置,例如:

  • db->用户(所有用户)->收藏夹
  

我的问题:

如何在一个用户和喜欢的位置之间建立联系?我认为这是一对多的关系。最好的解决方案是什么?

任何想法或一段代码都将不胜感激!

1 个答案:

答案 0 :(得分:2)

  

什么是最好的解决方案?

我知道每个人都在寻找最佳解决方案,但是在NoSQL数据库领域,没有没有最佳解决方案。您可以通过多种方法为像您这样的应用程序对数据库建模,并获得相同的结果,我将向您说明原因。在此之前,请查看我对此 post 的回答,以更好地理解“完美”,“最佳”或“正确”解决方案的概念,以防万一NoSQL数据库。

最好的解决方案是,只是在开玩笑:)使用arrays可以达到所需要的功能列表。您的数据库架构可能如下所示:

Firestore-root
   |
   --- users (Collection)
   |     |
   |     --- uid (document)
   |           |
   |           --- favoriteLocations: ["favoriteLocationId", "favoriteLocationId"]
   |
   --- locations (Collection)
         |
         --- locationId (document)
               |
               --- //Location details

如您所见,favoriteLocations数组仅包含位置ID。因此,为了获取位置详细信息,您应该获取这些ID并进行额外的数据库get()调用。

另一种方法不是存储位置ID数组,而是存储地图数组或位置对象数组。如果您有喜欢的位置数量合理,例如5、10甚至50,但不是 500,则此选项效果很好。如果您需要存储500个位置,那是什么原因将位置存储为收藏夹?

在这种情况下要记住的重要一件事是文档有限制。因此,在文档中可以放入多少数据方面存在一些限制。根据有关usage and limits的官方文档:

  

文档的最大大小:1 MiB(1,048,576字节)

如您所见,单个文档中的数据总数限制为1 MiB。当我们谈论存储文本时,您可以存储很多,但是随着数组变大,请注意此限制。

如果要存储单个文档允许存储的更多数据,则应使用集合。这样,您可以在每个用户对象下创建一个子集合,该子集合将作为文档(位置对象)保存。您的数据库结构应如下所示:

Firestore-root
   |
   --- users (Collection)
   |     |
   |     --- uid (document)
   |           |
   |           --- favoriteLocations (Collection)
   |                |
   |                --- favoriteLocationId (document)
   |                       |
   |                       --- //Location details
   |
   --- locations (Collection)
         |
         --- locationId (document)
               |
               --- //Location details

要查询如下所示的数据库,请使用以下代码行:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference favoriteLocationsRef = rootRef.collection("users").document(uid).collection(favoriteLocations);
favoriteLocationsRef.get(/* ... */);

另一种方法是对数据进行脱值处理并创建favoriteLocations子集合,作为顶级集合,如下所示:

Firestore-root
   |
   --- users (Collection)
   |     |
   |     --- uid (document)
   |           |
   |           --- //User details
   |
   --- locations (Collection)
   |     |
   |     --- locationId (document)
   |           |
   |           --- //Location details
   |
   --- favoriteLocations (Collection)
         |
         --- uid (document)
              |
              --- userFavoriteLocations (collection)
                    |
                    --- favoriteLocationId (document)
                           |
                           --- //Location details

相应的查询应如下所示:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference favoriteLocationsRef = rootRef.collection("favoriteLocations").document(uid).collection(userFavoriteLocations);
favoriteLocationsRef.get(/* ... */);

或更简单的方法如下:

Firestore-root
   |
   --- users (Collection)
   |     |
   |     --- uid (document)
   |           |
   |           --- //User details
   |
   --- locations (Collection)
   |     |
   |     --- locationId (document)
   |           |
   |           --- //Location details
   |
   --- favoriteLocations (Collection)
         |
         --- locationId (document)
               |
               --- uid: "uid"
               |
               --- //Other location details

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query query = rootRef.collection("favoriteLocations").whereEqualTo("uid", uid);
favoriteLocationsRef.get(/* ... */);

如您所见,我已经将用户的uid添加为location对象的属性,因此您可以简单地获取特定用户拥有的所有喜欢的位置。

您可以根据自己的应用选择哪种解决方案“最佳” :)

PS 请同时查看我在此 post 中给出的答案,其中我详细介绍了collectionsmapsarrays在Firestore中。