减少Firestore Android中的读取次数
我想减少读取次数,以便从
QuestionCollection
(QuestionCollection
数组)中获取问题的详细信息。
我的应用程序就像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"
其中comments
, likes
和views
是questionId
文档下的集合。 与在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)保存了大量的数据重复
是的,它确实。