Запрос Firestore и фильтрация, как это сделать для таблицы лидеров

# #firebase #flutter #google-cloud-firestore

Вопрос:

Я создаю приложение для задач с помощью flutter и показываю таблицу лидеров с 15 лучшими игроками за день, 15 лучшими за неделю и 15 лучшими за месяц. Пользователи могут фильтровать по дням недели или месяцам, и я показываю им список результатов, упорядоченных людьми с большинством завершенных задач.

Теперь вместо того, чтобы выполнять 3 запроса с днем, неделей, месяцем, я планировал выполнить запрос за месяц и отфильтровать неделю и день по клиенту. Это мой вопрос:

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

    getRanking() async {
        List<Data> _rankingResult = [];
    
    
        QuerySnapshot snapshot = 
        await FirebaseFirestore.instance
        .collection('tasks')
        .where('dateWhenProofed', isGreaterThanOrEqualTo: timeLimit)
        .limit(15) <- what about that?
        .get();
        
        snapshot.docs.forEach((document) {
          Data data = Data.fromJson(document.data());
          _rankingResult.add(data);
          _rankingResult.sort((a, b) => b.finishedTasksCount.compareTo(a.finishedTasksCount));
        });

    notifier.rankingList = _rankingResu<

  }
 

Мне интересно узнать об .limit() этом . Мне нужно только 15 лучших результатов для каждого фильтра, но что, если у нас здесь 1000 документов, как именно это limit() работает? Проверяет ли он все документы firestore из коллекции задач или проверяет только первые 15? Моя цель состоит в том, чтобы получить 15 самых высоких значений из этого, чтобы представить.

Также мне интересно, если у нас есть 15 результатов здесь, и я фильтрую их только по неделям, как я могу убедиться, что там также есть 15 результатов недели? Может быть, тогда мне не нужно ограничивать запрос на месяц? Было бы неплохо, если бы у кого-нибудь была идея по этому поводу.

Редактировать:

Ну, я не уверен на 100% (кто-то должен это подтвердить), но похоже, что limit() в запросе мы сокращаем данные, которые будут в списке 15 лучших. Я думаю, что мы можем избежать этого, добавив orderBy() параметр. Запрос сейчас будет выглядеть так:

 QuerySnapshot snapshot = 
    await FirebaseFirestore.instance
    .collection('tasks')
    .where('dateWhenProofed', isGreaterThanOrEqualTo: timeLimit)
    .orderBy('dateWhenProofed', descending: true) <--- added this line
    .limit(15)
    .get();

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

Применяя это, мы можем быть уверены, что получим все данные. Единственное, что сейчас не подходит, — это фильтрация только по дням недели и дням, потому что мы сказали в запросе, что timeLimit это 30 дней. Как мы можем сейчас лучше всего применять фильтрацию данных за неделю и день?

Ответ №1:

Вы правы в своем предположении с помощью .limit(), это дает вам только 15 лучших результатов. Вы можете просто изменить переменную timeLinit, чтобы получить лимит времени в день:

 //today
final limit = DateTime.now();

//one week
final limit = DateTime.now().subtract(const Duration(days: 7));