按desc排序的时间范围内的Firebase查询值 [英] Firebase query value in time range ordered by desc

查看:56
本文介绍了按desc排序的时间范围内的Firebase查询值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标:我想从按喜欢(降序)排序的无限集合中检索项目.我还想通过日期和结果计数来限制这些结果,例如前10名.

My goal: I want to retrieve items from an infinite collection ordered by likes (descending). I also want to limit these results by date and result count, e.g. top 10.

我无法适当地管理此案件.到目前为止,这是我得到的结果,但是我只希望获得前10个结果,并且缺少此限制.如果我在查询中放置 limit(),则不会得到正确的结果.

Im not able to manage this case in a nice way propably. This is what I got so far, but I want only the top 10 results and this limitation is missing. If i place a limit() inside the query I dont get the correct results.

Timestamp get timeLimit {
    final limit = DateTime.now().subtract(const Duration(days: 30));
    return Timestamp.fromDate(limit);
  }

QuerySnapshot snapshot = 
    await FirebaseFirestore.instance
    .collection('data')
    .where('date', isGreaterThanOrEqualTo: timeLimit)
    .orderBy('date', descending: true)
    .get();

snapshot.docs.forEach((document) {
              Data data = Data.fromJson(document.data());
              resultList.add(data);
              resultList.sort((a, b) => b.likes.compareTo(a.likes));
            });

推荐答案

您正在达到Cloud Firestore的限制.如果您有一个具有范围比较的过滤器(<,< =,>,> =),则您的第一次排序必须在同一字段上.[参考:https://cloud.google.com/firestore/docs/query-data/order-limit-data]

You are hitting a limit of Cloud Firestore. If you have a filter with a range comparison (<, <=, >, >=), your first ordering must be on the same field. [Ref: https://cloud.google.com/firestore/docs/query-data/order-limit-data]

在您的情况下,第二个orderBy(在 likes 上)仅在完全相同的 date 的组内有效,这将毫无用处.

In your case, the second orderBy (on likes) will have an effect only within groups of exactly the same date, which will be pretty useless.

如果您的目标是跟踪每日/每周/每月的TOP 10 ,则可能应该在Firestore中维护该列表,而不是为每个访问者计算列表.

If your goal is to keep track of the daily / weekly / monthly TOP 10, you should probably maintain that list in Firestore instead of computing the lists for each visitor.

您可以让每个[要定义的持续时间]都运行一个Cloud Function,以重置TOP 10列表.

You could have a Cloud Function running every [duration to be defined] to reset the TOP 10 lists.

这需要付出一定的代价,但是 read 操作对于每个访问者来说都会便宜得多.

This comes at a cost but the read operations will be dramatically cheaper for each visitor.

这样的函数可以写成:

const admin = require('firebase-admin');
admin.initializeApp();

const db = admin.firestore();


exports.computeTopTenLists = functions.pubsub.schedule('every 2 hours').onRun((context) => {
  var millisecondsInOneDay = 24 * 60 * 60 * 1000;
  var dailyStart = new Date(Date.now() - millisecondsInOneDay);
  var weeklyStart = new Date(Date.now() - 7 * millisecondsInOneDay);
  var monthlyStart = new Date(Date.now() - 30 * millisecondsInOneDay);
  date.setDate(date.getDate() - 7);

  // Top 10 list (sorted by likes, descending)
  var dailyTopTen = [];
  var weeklyTopTen = [];
  var monthlyTopTen = [];

  db.collection('data').where("date", ">=", monthlyStart ).get().then((querySnapshot) => {
    [
      { list: dailyTopTen, start: dailyStart },
      { list: weeklyTopTen, start: weeklyStart },
      { list: monthlyTopTen, start: monthlyStart },
    ].forEach((curr) => {
      curr.list.push(querySnapshot[0].data());
      querySnapshot.slice(1).forEach((doc) => {
        var data = doc.data();
        data['id'] = doc.id;
        if (data['date'] > curr.start && data['likes'] > curr.list[curr.list.length-1]) {
          curr.list.push(data);
          curr.list.sort((a, b) => (a.likes > b.likes ? -1 : 1));
          curr.list = curr.list.slice(0, 10);
        }
      });
    });
  })

  db.collection('top-ten').document('lists').set({
    daily: dailyTopTen.map(data => ({id: data['id'], title: data['title']})),
    weekly: weeklyTopTen.map(data => ({id: data['id'], title: data['title']})),
    monthlyly: monthlyTopTen.map(data => ({id: data['id'], title: data['title']})),
  });

  return null;
});

只需阅读一份文档,您将获得前三名的前三名列表.

You would get the three Top 10 lists with just one document read.

这篇关于按desc排序的时间范围内的Firebase查询值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆