Комплексные запросы Firebase во флаттере - PullRequest
3 голосов
/ 31 мая 2019

Я работаю с коллекцией в Firebase, которая хранит информацию о продуктах.Ранее я просто выбирал все продукты, а затем применял к ним фильтры на стороне клиента.Мне сказали, что мне нужно применить эти фильтры в запросе, чтобы уменьшить количество операций чтения, которые понадобятся Firebase, так как будет очень много продуктов.

Я попытался объединить несколько операторов .where (), но это не дает того эффекта, который мне нужен, я прочитал в другом посте, что несколько операторов .orderBy () сломают запрос, но для того, чтобыпроверьте другие поля, такие как цена, вывод говорит мне, что мне нужно сначала заказать orderBy ().Можно применить любое количество этих фильтров или ни один из них в зависимости от настроек.Я использую переменную lastVisible внизу для .startAfter в отдельной функции для получения большего количества продуктов.Есть ли какой-нибудь способ создать запрос, который я хочу сделать таким образом?Я также хотел бы знать, возможно ли сделать что-то вроде .where ('field', isEqualTo: x или y или z).

    Query productQuery = Firestore.instance.collection('Products');

    if(selectedCategories != null)
    for(int i = 0; i < selectedCategories.length; i++)
      productQuery = productQuery.where('category', isEqualTo: selectedCategories[i]);

    if(minPrice > 0 && maxPrice > 0)
    {
      productQuery = productQuery.orderBy('price').where('price', isGreaterThanOrEqualTo: minPrice).where('price', isLessThanOrEqualTo: minPrice);
    }
    else if(minPrice > 0)
      productQuery = productQuery.orderBy('price').where('price', isGreaterThanOrEqualTo: minPrice);

    else if(maxPrice > 0)
      productQuery = productQuery.orderBy('price').where('price', isLessThanOrEqualTo: maxPrice);

    if(!showUnavailableItems)
      productQuery = productQuery.where('status', isEqualTo: 'available');

    switch(selectedCondition)
    {
      case 'Acceptable':
        productQuery = productQuery
                      .where('condition', isEqualTo: 'Acceptable')
                      .where('condition', isEqualTo: 'Good')
                      .where('condition', isEqualTo: 'Very Good');
        break;
      case 'Good':
        productQuery = productQuery
                      .where('condition', isEqualTo: 'Acceptable')
                      .where('condition', isEqualTo: 'Good');
        break;
      case 'Very Good':
        productQuery = productQuery
                      .where('condition', isEqualTo: 'Acceptable');

        break;
      default:
        break;
    }

    productQuery = productQuery.orderBy('id');

    QuerySnapshot myQuery = await productQuery.getDocuments();
    List<DocumentSnapshot> productSnaps = myQuery.documents;
    print("INITIAL PRODUCT SNAPS LENGTH: ${myQuery.documents.length}");

    if(productSnaps.length != 0)
      lastVisible = productSnaps[productSnaps.length -1].data['id'];

Когда применяются фильтры условия или категории, результатвсегда 0 документов.Использование фильтров minPrice и maxPrice по отдельности работает, но вместе также возвращает 0 продуктов.Я не получил никаких ошибок, кроме тех, что создавались в Firebase.

1 Ответ

1 голос
/ 31 мая 2019

Мне сказали, что мне нужно применить эти фильтры в запросе, чтобы уменьшить количество операций чтения

Это верно, поскольку в Firestore все относится к числу операций чтения и записи..

Я попытался объединить несколько операторов .where (), но это не дает того эффекта, который мне нужен

Почему вы используете это?Я много раз использовал функцию where() для фильтрации данных в базе данных Cloud Firestore и никогда не подводил.

В другом посте я читал, что несколько операторов .orderBy () сломают запрос

Это не правда!Пожалуйста, проверьте мой ответ из следующего поста:

Пожалуйста, такжепомните, что если вы используете несколько вызовов orderBy() methiod, вы получите предупреждение, подобное следующему:

Status {code = FAILED_PRECONDITION, description = Для запроса требуется индекс.

Так что не забудьте создать индекс в консоли Firebase.

Есть ли какой-нибудь способ создать запрос, который я хочу сделать таким образом?

Да, вы можете использовать все опции, которые вы уже упомянули.

Я также хотел бы знать, возможно ли сделать что-то вроде .where ('field', isEqualTo: x или y или z).

Нет, это невозможно, но есть способ, который поможет вам достичь того же.Для этого, пожалуйста, смотрите мой ответ из следующего поста:

Итаквместо использования массива используйте карту и объедините несколько вызовов where().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...