减少 Firestore Android 中的读取次数

Xar*_*mer 6 java android firebase google-cloud-firestore

我想减少阅读次数,以便从QuestionCollection(Array of Questions) 中获取问题的详细信息。

我的应用程序就像是 stackoverflow 的一部分

我想显示一个问题有多少赞、浏览量和评论。所以为了处理这个我创建了多个集合

问题集

  • ID
  • 标题
  • 创建日期

评论集

  • ID
  • 评论
  • 创建日期

问题点赞

  • 问题ID
  • 用户身份

问题视图

  • 问题ID
  • 用户身份

问题标签

  • 问题ID
  • 标签ID

我认为CommentCollection (comments) 只属于一个问题。所以我正在考虑QuestionCollection像数组或集合一样合并(但它需要另一个读取命中)。哪个更好

我想totalViews,totalLikes在 QuestionCollection中添加两个变量的( )。但是每次我都必须检查这个问题是否被这个用户喜欢或被这个用户查看。

给我一个建议或替代方案,这样我就可以尽可能少地获取问题详细信息

编辑

为了显示视图计数, 我迭代并计算QuestionViews 集合,其中 questionID == myQuestionID

为了显示喜欢计数, 我迭代并计算QuestionLikes 集合,其中 questionID == myQuestionID

为什么我不将它添加到 QuestionCollection?因为我想展示最多查看和最喜欢的问题,例如 stackoverflow。如果我将它添加到 QuestionCollection 我怎么知道最喜欢和最多查看的问题。

Ale*_*amo 10

我能想到的最有效的模式如下:

Firestore-root
    |
    --- questions (collections)
    |     |
    |     --- questionId (document)
    |            |
    |            --- questionId: "02cubnmO1wqyz6yKg571"
    |            |
    |            --- title: "Question Title"
    |            |
    |            --- date: August 27, 2018 at 6:16:58 PM UTC+3
    |            |
    |            --- comments (colletion)
    |            |     |
    |            |     --- commentId
    |            |            |
    |            |            ---commentId: "5aoCfqt2w8N8jtQ53R8f"
    |            |            |
    |            |            ---comment: "My Comment"
    |            |            |
    |            |            ---date: August 27, 2018 at 6:18:28 PM UTC+3
    |            |
    |            --- likes (colletion)
    |            |     |
    |            |     --- likeId (document)
    |            |            |
    |            |            --- userId: true
    |            |
    |            --- views (colletion)
    |            |     |
    |            |     --- viewId (document)
    |            |            |
    |            |            --- userId: true
    |            |
    |            --- tags ["tagId", "tagId"]
    |
    --- tags (collections)
          |
          --- tagId (document)
                |
                --- tagId: "yR8iLzdBdylFkSzg1k4K"
                |
                --- tagName: "Tag Name"
Run Code Online (Sandbox Code Playgroud)

其中comments,likesviewsquestionId文档下的集合。与在 Firebase 实时数据库中显示问题列表不同,您会下载整个问题对象,而在 Cloud Firestore 中这不再是问题。因此,为了避免使用where方法进行查询,您可以简单地得到一个特定的问题,如下所示:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
DocumentReference questionIdRef = rootRef.collection("questions").document(questionId);
questionIdRef.get().addOnCompleteListener(/* ... */);
Run Code Online (Sandbox Code Playgroud)

因为一个问题可以有成百上千甚至更多的评论、喜欢和查看,所以将数据存储到数组中对您没有帮助。根据官方文档

Cloud Firestore 已针对存储大量小型文档进行了优化。

例如,要获取特定问题的所有评论,可以使用以下查询:

Query query = rootRef.collection("questions/"+questionId+"comments").orderBy("date", Query.Direction.DESCENDING);
Run Code Online (Sandbox Code Playgroud)

因为一个问题只能有几个标签,所以你可以简单地使用一个数组。要获取带有特定标签的所有问题,您可以使用以下查询:

Query query = rootRef.collection("questions/"+questionId+"tags").whereArrayContains("tags", tagId);
Run Code Online (Sandbox Code Playgroud)

还有一点要记住,即使tags对象作为数组存储在数据库中,document.get("tags")也将返回 anArrayList而不是 an array

如果您还想计算收藏中喜欢的数量或任何其他数量的文档,请参阅我在这篇文章中的回答。

编辑:

根据您的评论:

如果我想向用户展示最喜欢的问题。我怎么能这样做?

您应该在问题对象中添加喜欢的数量作为属性,然后您可以根据它查询数据库,如下所示:

Query query = rootRef.collection("questions").orderBy("numberOfLikes", Query.Direction.DESCENDING);
Run Code Online (Sandbox Code Playgroud)

根据这个,你还可以存储喜欢在火力地堡实时数据库的数量,可以增加/减少使用它火力地堡交易

其次,如果我想显示与数学标签相关的所有问题(显示所有具有数学标签的问题)?

如上所述,您可以利用该whereArrayContains方法。您还可以将标签存储为 String 而不是 id。为此,您需要更改此结构:

--- tags ["tagId", "tagId"]
Run Code Online (Sandbox Code Playgroud)

--- tags ["mathematics", "chemistry"]
Run Code Online (Sandbox Code Playgroud)

代码应该是这样的:

Query query = rootRef.collection("questions/"+questionId+"tags").whereArrayContains("tags", "mathematics");
Run Code Online (Sandbox Code Playgroud)

语句(userId: true) 节省了大量数据重复

是的,它确实。