如何从具有属性匹配项或子集合不匹配的父集合中从Cloud Firestore检索文档

时间:2020-07-22 18:14:00

标签: firebase google-cloud-firestore

我有这样的云Firestore设置-

/ questions / {qid} / attempts / {attemptId}

问题文档和尝试文档的结构如下-

questionID
  questionText: "QuestionText"
  Options: ['option1','option2']
  class: [1,2]
  subject: science
  ...

attemptdId
 questionID: <qid>
 numAttempts: 5
 correctAttempts: 2
 uid:uid
 lastAttemptIsCorrect:true/false
 ...

对于提供给用户的每个问题,尝试都存储在子集合尝试文档中-每个用户每个问题仅存储1个尝试文档,相同问题的每次尝试都会更新现有的尝试文档。

我想找问题

  1. class:1,subject:science,用户未尝试(未尝试)
  2. 类别:1,主题:科学,用户上次尝试不正确的尝试

如何在当前结构中实现这一目标?还是可以使用其他结构来实现?

2 个答案:

答案 0 :(得分:0)

您可以使用相同的结构来实现。以下是建议的步骤,并带有推荐的链接:

  1. 首先,使用数组包含查询所有问题集合以过滤类,然后过滤主题,如下所示:
    // returns questins that of class 1 and subject science
    questionResults = db.collection('questions`).where('class', 'array-contains', 
      '1').where('subject','==','science').valuesChanges();

https://firebase.google.com/docs/firestore/query-data/queries#array_membership

  1. 现在遍历从头获得的每个问题结果(您需要订阅才能获得实际的响应,如果您不知道这一点,请告诉我)。 对于每个迭代问题,现在检索子集合attempts并 检查其numAttempts是否为0以确定是否尝试过。 您可以通过以下方式获取子集合(尝试)文档:
    db.collection('questions').doc('question_uid').collection('attempts').
     doc('attempt_uid')

如果条件匹配,我们想将此问题推送到数组。以下仅是逻辑而非实际代码。例如。

    desiredQuestionList = [];
    questionResults.forEach(question=>{
      // fetch attempts doc of question
       if (attempt doc has 0 attempts count){
          desiredQuestionList.push(question)
       }
     }

答案 1 :(得分:0)

无法通过单个查询来实现。但是您可以使用Collection Group Queries

集合组查询从具有相同ID(例如attempts)的所有集合中检索数据。然后,您可以获取上次尝试不正确的所有尝试:

var attempts = db.collectionGroup('attempts').where('lastAttemptIsCorrect', '==', true);

然后,您必须将尝试与带有问题ID的问题相关联。

AFAIK,这是目前受支持的最佳方法