减少Firestore Android中的读取次数

我想减少读取次数,以便从QuestionCollectionQuestionCollection数组)中获取问题的详细信息。

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

我想表明一个问题有多少喜欢,观点和评论 。 所以为了处理这个我创建了多个集合

QuestionCollection

  • ID
  • 标题
  • 创建日期

CommentCollection

  • ID
  • 评论
  • 创建日期

QuestionLikes

  • QuestionID
  • 用户名

QuestionViews

  • QuestionID
  • 用户名

问题标签

  • QuestionID
  • 标签识别

我认为CommentCollection (评论)只属于一个问题。 所以我想在QuestionCollection中加入像数组或集合(但它需要另一个读取命中)。 哪一个更好

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

给我一个建议或替代方案, 这样我可以获得最少的点击来获取问题详细信息

编辑

对于显示视图计数,我迭代并计算QuestionViews集合中的questionID == myQuestionID

对于显示喜欢计数我迭代并计算QuestionLikes Collection其中questionID == myQuestionID

为什么我不将它添加到QuestionCollection? 因为我想显示最多的被观看者和最喜欢像stackoverflow这样的问题。 如果我将它添加到QuestionCollection我怎么能知道最喜欢和最常见的问题。

我能想到的最有效的架构如下:

 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" 

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

 FirebaseFirestore rootRef = FirebaseFirestore.getInstance(); DocumentReference questionIdRef = rootRef.collection("questions").document(questionId); questionIdRef.get().addOnCompleteListener(/* ... */); 

因为您可以对单个问题拥有数百,数千甚至更多的评论,喜欢和观看,所以将数据存储到数组中对您无济于事。 根据官方文件 :

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

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

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

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

 Query query = rootRef.collection("questions/"+questionId+"tags").whereArrayContains("tags", tagId); 

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

如果您还想计算集合中的喜欢数量或任何其他数量的文档,请参阅此post中的答案。

编辑:

根据你的意见:

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

你应该在问题对象中添加喜欢的数量作为属性,然后你可以像这样查询数据库:

 Query query = rootRef.collection("questions").orderBy("numberOfLikes", Query.Direction.DESCENDING); 

根据此,您还可以在Firebase实时数据库中存储喜欢的数量,您可以使用Firebase事务来增加/减少喜欢。

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

如上所述,您可以采用“方法”的优点。 您还可以将标记存储为String而不是id。 为此,您需要更改此结构:

 --- tags ["tagId", "tagId"] 

 --- tags ["mathematics", "chemistry"] 

代码应如下所示:

 Query query = rootRef.collection("questions/"+questionId+"tags").whereArrayContains("tags", "mathematics"); 

语句(userId:true)保存了大量的数据重复

是的,它确实。