需要从Firebase过滤,分页和订购数据的建议

时间:2019-05-24 05:52:22

标签: javascript reactjs firebase google-cloud-firestore

上下文

我目前正在一个由ReactJS网站组成的个人项目中,该网站显示了一个列表导师,可以通过与不同组件进行交互以各种方式对其进行过滤。我制作了一个组件,该组件从指定用于教师信息的Firestore集合中获取一系列教师信息,然后将其显示为列表。 现在可以过滤的教师集合中每个文档的字段是一个主题数组,其中包含各种不同主题的名称,描述每小时收费的价格字段和姓氏字段。除了过滤之外,还可以按姓氏的字母顺序(从最低到最高的每小时价格)对教师进行排序。

我可以毫无问题地过滤所有这些内容,尽管我必须在客户端进行主题过滤。这是因为,如果我使用集合引用上的orderBy()方法按姓氏字段按字母顺序对数据进行排序,或按价格字段按数字顺序对数据进行排序,则将无法添加where()查询来搜索其他字段。 例如,如果我要查询firebase,以按学生姓氏的顺序返回导师快照的快照,并且还想过滤掉不教授物理的学生,则必须编写如下查询: / p>

tutorRef.orderBy("lastname").where("subjects", "array-contains", "Physics 1")

但这会引发错误。根据{{​​3}},这是因为在特定字段上使用orderBy时,还必须在同一字段上使用后续where()语句。 为了解决这个问题,我完全删除了where()语句

tutorRef.orderBy("lastname")

并编写了一个函数,该函数遍历返回的导师信息数组,并删除该导师的主题数组中未包含过滤器组件指定的主题的任何导师。

如果有帮助,这就是这种方法的样子。

getTutors = (filterType) => {

    var wholeData = [];

    // Get all tutors from tutors collection in firebase
    var query = db.collection("tutors")

    // Order by a custom filterType, such as "lastname" or "price"
    query = query.orderBy(filterType)
    query.get().then(snapshot => {
      // Push individual tutor information from snapshot to array
      snapshot.forEach(doc => {
        wholeData.push(doc.data());
      })

      // If the current subject filter value is "No selection then don't filter, 
      // otherwise do filter by subject
      if (this.state.subjectFilterValue != 'No selection') {
        wholeData = wholeData.filter((tutor) => {
          return tutor.info.subjectnames.includes(this.state.subjectFilterValue)
        })
      }

      // Filter out tutors that aren't in the filter price range
      wholeData = wholeData.filter((tutor) => {
        return (tutor.info.price >= this.state.minPrice &&
          tutor.info.price <= this.state.maxPrice) ||
          tutor.info.price == -1
      })

      // store tutor data in state
      this.setState({
        tutors: wholeData
      })
    }).catch(error => {
      console.log('something gone bad:', error);
    })
}

问题

我想实施分页,一次只显示五个导师。这将需要将查询更改为

tutorRef.orderBy("lastname").where("subjects", "array-contains", "Physics 1").limit(5)

然后从此查询中获取最后一个文档,并使用startAfter对下一页的导师开始新的查询

但是,如果我应用客户端主题过滤的方法,则会从列表的不同页面中删除一些导师,并在某些页面上留下数量不一致的导师,因为并非所有导师都可以教授特定主题。

我想解决的唯一方法是:

  1. 删除orderby()查询方法并且根本无法对我的列表进行排序,以尝试能够过滤这样的主题

    tutorRef.where(“ subjects”,“ array-contains”,“ Physics 1”)。limit(5)

  2. 通过请求集合中的所有导师来
  3. 在客户端上分派导师,这最终可能会非常缓慢且繁琐,无法满足Firestore的要求。

我是否正在考虑解决这个问题的方法?

0 个答案:

没有答案