【问题标题】:Reduce number of read in Firestore Android减少 Firestore Android 中的读取次数
【发布时间】:2019-02-01 22:34:58
【问题描述】:

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

我的应用就像 stackoverflow 的一部分

我想显示一个问题有多少点赞、浏览和cmets。因此,为了处理这个问题,我创建了多个集合,例如

问题集合

  • 身份证
  • 标题
  • 创建日期

评论集合

  • 身份证
  • 评论
  • 创建日期

问题喜欢

  • 问题 ID
  • 用户 ID

问题视图

  • 问题 ID
  • 用户 ID

问题标签

  • 问题 ID
  • 标签ID

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

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

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

编辑

用于显示观看次数 我迭代并计算 QuestionViews Collection where questionID == myQuestionID

显示喜欢计数 我迭代并计数 QuestionLikes Collection where questionID == myQuestionID

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

【问题讨论】:

  • 你说你想减少读取次数。您执行了多少 mant 读取操作以及您希望减少多少?
  • 查看编辑@AlexMamo
  • 我明白了。我马上给你写一个答复。

标签: java android firebase google-cloud-firestore


【解决方案1】:

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

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(/* ... */);

因为一个问题可以有数百、数千甚至更多的 cmets、喜欢和视图,将数据存储到数组中对您没有帮助。根据official documentation

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

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

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 中的回答。

编辑:

根据您的 cmets:

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

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

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

根据this,您还可以将点赞数存储在 Firebase 实时数据库中,您可以使用 Firebase Transactions 增加/减少它。

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

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

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

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

代码应该是这样的:

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

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

是的。

【讨论】:

  • 如果我想向用户展示最喜欢的问题。我怎么能这样。其次,如果我想显示与数学等标签相关的所有问题(显示所有具有数学标签的问题)??
  • 和@AlexMamo的语句(userId: true)节省了大量的数据重复
  • @XarEAhmer 请查看我的更新答案,我也在编辑部分回答了您的新问题。
  • @XarEAhmer 您也可以等待她的回答,但如果您认为我的回答对您有所帮助,请考虑接受并投票。我会很感激的。谢谢!
  • @akshaybhange 由于 cmets 存在于不同的集合中,因此将单独计算。
猜你喜欢
  • 1970-01-01
  • 2021-04-04
  • 2021-11-23
  • 2021-06-08
  • 1970-01-01
  • 2021-05-22
  • 2019-12-29
  • 2020-03-31
  • 1970-01-01
相关资源
最近更新 更多