У меня есть приложение firebase, которое включает в себя коллекцию, содержащую сообщения, которые были сделаны в приложении, каждый с документом, содержащим данные для сообщения. Как пользователь, вы можете ставить лайки постам, и UID понравившихся постов сохраняются в пользовательском документе. В прошлом приложения я хочу иметь возможность получать все сообщения, которые понравились пользователю. У меня есть два способа сделать это:
Первый вариант Я мог бы использовать параметр поля где:
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 управляет этими запросами.
Между этими двумя подходами не будет значительной разницы в производительности. Лично я предпочитаю получать каждое сообщение по его идентификатору, поскольку это означает, что я не могу иметь дело с ограничением в 10 значений для
in
запроса. Но, как уже было сказано: это только личное предпочтение.Единственным лучшим вариантом было бы, если бы вы могли получить избранное для пользователя с помощью запроса равенства (
==
) или запроса диапазона (>
,<
,>=
,<=
), но я не видел варианта для этого для этого варианта использования .Другой альтернативой является хранение избранных сообщений пользователя в отдельной (под) коллекции для этого пользователя, чтобы вы могли просто прочитать эту коллекцию целиком. Это означает, что вы будете дублировать сообщения, когда они пишутся, и поддерживать их в актуальном состоянии, когда они обновляются, но взамен вы получите более быстрое и масштабируемое поведение чтения.
Это распространенный компромисс при использовании баз данных NoSQL: это реализация классического компромисса между пространством и временем.