Эффективность запросов к базе данных с использованием поля where по сравнению с альтернативой

#swift #firebase #google-cloud-firestore

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

Вопрос:

У меня есть приложение firebase, которое включает в себя коллекцию, содержащую записи, которые были созданы в приложении, каждая с документом, содержащим данные для записи. Как пользователь, вы можете поставить лайк на публикацию, и идентификаторы ваших понравившихся записей сохраняются в пользовательском документе. В прошлом приложении я хочу иметь возможность извлекать все сообщения, которые понравились пользователю. У меня есть два способа сделать это:

Первый вариант, который я мог бы использовать для параметра where field:

     static func getLikedPosts(likedIDs: [String], completion: @escaping ((_ data: [Post]) -> Void))  {
        db.collection("posts").whereField("postID", in: likedIDs).getDocuments {(querySnapshot, err) in
            if let err = err {
                print(err)
            } else {
                var listings: [Listing] = []

                for doc in querySnapshot!.documents {
                   
                    // ...
                    let post = Post()
                    posts.append(post)
                }

                completion(posts)
            }
        }
    }
  

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

     static func getPost(listingID: String, completion: @escaping ((_ data: Post) -> Void)) {
        db.collection("posts").document(postID).getDocument { (doc, err) in
            if let err = err {
                print(err)
            } else {
                if let doc = doc, doc.exists {
                    
                    
                    if let data = doc.data() {
                        
                        // ...
                        let post = Post()
                        completion(post)
                    }

                }
            }
        }
    }
  

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

     static func getLikedPosts(likedIDs: [String], completion: @escaping ((_ data: [Post]) -> Void)) {
        var posts = [Post]()
        for id in likedIDs {
            getPost(postID: id) { (post) in

                listings.append(post)
                
                if posts.count == likedIDs.count {
                    completion(posts)
                }
            }
        }
    }
  

Мой вопрос в том, какой из этих двух вариантов более эффективен / масштабируем для большого количества сообщений или есть лучший вариант? Я бы предположил, что использование поля where будет более сложным по времени, но не уверен в том, как firebase управляет этими запросами.

Ответ №1:

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

Единственным лучшим вариантом было бы, если бы вы могли получить избранное для пользователя с помощью запроса равенства ( == ) или запроса диапазона ( > , < , >= , <= ), но я не видел для этого варианта использования.

Другой альтернативой является сохранение избранных сообщений пользователя в отдельной (вспомогательной) коллекции для этого пользователя, чтобы затем вы могли просто прочитать всю эту коллекцию. Это означает, что вы будете дублировать записи при их записи и поддерживать их в соответствии с данными при их обновлении, но взамен вы получите более быстрое и масштабируемое поведение чтения.

Это обычный компромисс при использовании баз данных NoSQL: и является реализацией классического компромисса между пространством и временем.