Эффективный запрос большого количества документов Firestore и ограничение количества результатов?

#ios #swift #firebase #google-cloud-firestore

# #iOS #swift #firebase #google-облако-firestore

Вопрос:

Более общий вопрос: как можно использовать Swift для запроса сотен или даже тысяч документов, хранящихся в Firestore , и ограничить количество результатов некоторой суммой (скажем, 100).

В документах Firebase я нашел .limit(some_number) функцию, которую вы можете привязать к концу .where запроса. Проблема в том, что если some_number равно 100, то, похоже, он выполняет поиск только по 100 документам, а не продолжает поиск, пока не получит 100 результатов. Если только 60 из 100 этих документов соответствуют тому, что вы искали, тогда вы получаете 60 вместо того, чтобы продолжать поиск, пока не дойдете до 100.

Я что-то упускаю?

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

 let db = Firestore.firestore().collection("users")

db.whereField(gameKey, isEqualTo: gameValue)
  .whereField(rank, isEqualTo: rankValue)
  .whereField(mic, isEqualTo: micValue)
  .whereField(platform, isEqualTo: platformValue)
  .limit(5)
  .getDocuments { (snapshot, error) in
    for document in (snapshot?.documents)! {
      print("Found a player that plays this game")
    }
  }
 

gameValue — это bool (если игрок играет в игру, то это true)

Значение ранга — это строка (например: «Gold 2»)

mic — это bool (если у игрока есть mic, то это true)

платформа — это строка (например, «PS4»)

Редактирование 1: добавлен код для контекста

Комментарии:

1. Это не так, как это должно работать. Не видя вашего запроса и не имея представления о данных, которые вы пытаетесь запросить, на самом деле невозможно сказать, что здесь происходит.

2. @DougStevenson я обновил свой вопрос своим запросом и какие данные я пытаюсь запросить

Ответ №1:

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

Я создал FireStore со 100 пользователями в следующем формате

 uid_0
    gameValue: "1" //or "0"
    micValue: "1"
    platformValue: "1"
    rankValue: "1"
 

для 50 пользователей было установлено значение gameValue равным «0», для остальных 50 установлено значение «1»

Затем я запустил следующий фрагмент кода 10 раз.

 func readGameData() {
    let usersColl = self.db.collection("users")
    let query = usersColl
        .whereField("gameValue", isEqualTo: "1")
        .whereField("rankValue", isEqualTo: "1")
        .whereField("micValue", isEqualTo: "1")
        .whereField("platformValue", isEqualTo: "1")
        .limit(to: 25)

    query.getDocuments { (querySnapshot, err) in
        if let err = err {
            print("Error getting documents: (err)")
            return
        }
        if let snap = querySnapshot {
            if snap.count > 0 {
                for document in snap.documents {
                    let key = document.documentID
                    print("player: (key) plays this game")
                }
            } else {
                print("no players play this game")
            }
        } else {
            print("no data returned")
        }
    }
}
 

В ответ был выдан список из первых 25 игроков, которые соответствовали показанным критериям запроса. Затем я изменил параметр .limit на разные значения от 1 до 25 до 100, и он вернул 1 результат, затем 25 результатов, затем 50 результатов. Имея в виду, что было ровно 50 игроков с значением gameValue 1.

Таким образом, это может указывать на то, что ошибка кроется в другом месте кода или, возможно, существует несоответствие в том, как структурированы свойства FireStore.

Ответ №2:

Похоже, вы неправильно поняли, как работают запросы Firestore. Ограничение, которое вы можете указать, — это максимальное количество документов, которые может вернуть запрос, а не максимальное количество документов, которые он может искать.

Если вы используете limit(100) запрос on, запрос возвращает первые 100 документов, соответствующих запросу. Если в запросе соответствует менее 100 документов, он вернет все совпадения.

Комментарии:

1. Итак, в моем случае, в частности, есть коллекция под названием «пользователи» с пользовательскими документами в ней. Во всех пользовательских документах есть игры, в которые они играют (мое приложение находит товарищей по команде для людей). Если я запрашиваю с помощью .where(playsGame, isEqualTo: true), я получаю обратно 5 из своих 10 тестовых документов, что означает, что в коллекции есть 5 пользователей, которые играют в эту конкретную игру. Когда я добавляю .limit(5) в конце этого запроса, я получаю только 3 документа обратно. По совпадению, из первых 5 пользовательских документов в коллекции только 3 играют в эту игру. Следовательно, почему мне кажется, что он ищет только предельное количество документов.

2. Предполагается, что запросы работают не так, и я также никогда не видел, чтобы это происходило на практике. Конечно, всегда возможно, что где-то есть ошибка в SDK или на стороне сервера. Можете ли вы воспроизвести проблему с меньшим количеством полей и документов, чтобы мы могли попытаться воспроизвести ее локально?

3. Я сделаю небольшую демонстрацию и посмотрю, смогу ли я ее воспроизвести. К сожалению, вероятно, до этого не дойдет до завтра. Опубликую еще один комментарий, когда смогу его воспроизвести. И я понимаю, что это не так, как они должны работать, поэтому я схожу с ума, задаваясь вопросом, почему это не работает. Это просто один из тех дней, ха-ха