Мне интересно, можно ли получить несколько документов по списку идентификаторов за одну поездку туда и обратно (сетевой вызов) в Firestore.
105
Мне интересно, можно ли получить несколько документов по списку идентификаторов за одну поездку туда и обратно (сетевой вызов) в Firestore.
a
,b
,c
чтобы сделать что - то. Я запрашиваю все три параллельно в отдельных запросах.a
занимает 100 мс,b
занимает 150 мс иc
занимает 3000 мс. В результате мне нужно подождать 3000 мс, чтобы выполнить задачу. Это будетmax
из них. Это будет более рискованно, когда количество документов, которые нужно получить, велико. В зависимости от статуса сети, я думаю, это может стать проблемой.SELECT * FROM docs WHERE id IN (a,b,c)
займет одинаковое количество времени? Я не вижу разницы, так как соединение устанавливается один раз, а остальное передается по конвейеру. Время (после первоначального установления соединения) - это время загрузки всех документов + 1 поездка туда и обратно, одинаковая для обоих подходов. Если он ведет себя по-другому, не могли бы вы поделиться образцом (как в моем связанном вопросе)?Ответы:
если вы находитесь в Node:
https://github.com/googleapis/nodejs-firestore/blob/master/dev/src/index.ts#L701
Это специально для серверного SDK
ОБНОВЛЕНИЕ: «Cloud Firestore [клиентский sdk] теперь поддерживает IN запросы!»
https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html
myCollection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"])
источник
firebase.firestore.FieldPath.documentId()
а не'id'
Они только что объявили об этой функции, https://firebase.googleblog.com/2019/11/cloud-firestore-now-supports-in-queries.html .
Теперь вы можете использовать такие запросы, но помните, что размер ввода не может быть больше 10.
userCollection.where('uid', 'in', ["1231","222","2131"])
источник
db.collection('users').where(firebase.firestore.FieldPath.documentId(), 'in',["123","345","111"]).get()
firebase.firestore.FieldPath.documentId()
На практике вы бы использовали firestore.getAll как это
или с синтаксисом обещания
источник
Нет, прямо сейчас нет возможности пакетировать несколько запросов на чтение с помощью Cloud Firestore SDK и, следовательно, нет способа гарантировать, что вы можете прочитать все данные сразу.
Однако, как сказал Франк ван Пуффелен в комментариях выше, это не означает, что выборка трех документов будет в 3 раза медленнее, чем выборка одного документа. Прежде чем делать выводы, лучше провести собственные измерения.
источник
Вы можете использовать такую функцию:
Его можно вызвать с одним идентификатором:
или массив идентификаторов:
источник
Конечно, лучший способ сделать это - реализовать фактический запрос Firestore в облачной функции? Тогда от клиента к Firebase будет только один звонок туда и обратно, что, похоже, именно то, о чем вы просите.
В любом случае вы действительно хотите сохранить всю логику доступа к данным, как на этой стороне сервера.
Внутри, вероятно, будет такое же количество вызовов самой Firebase, но все они будут осуществляться через сверхбыстрые межсоединения Google, а не через внешнюю сеть, и в сочетании с конвейерной обработкой, которую объяснил Фрэнк ван Пуффелен, вы должны получить отличную производительность от этот подход.
источник
Если вы используете флаттер, вы можете сделать следующее:
Это вернет Future,
List<DocumentSnapshot>
который вы можете повторять по своему усмотрению.источник
Вот как вы могли бы сделать что-то подобное в Kotlin с Android SDK.
Может не обязательно быть в одном цикле, но он эффективно группирует результат и позволяет избежать множества вложенных обратных вызовов.
Обратите внимание, что выборка определенных документов намного лучше, чем выборка всех документов и фильтрация результата. Это потому, что Firestore взимает плату за набор результатов запроса.
источник
Надеюсь, это вам поможет, у меня это работает.
источник
В настоящее время это невозможно в Firestore. Я не понимаю, почему ответ Александра принят, решение, которое он предлагает, просто возвращает все документы из коллекции «пользователей».
В зависимости от того, что вам нужно сделать, вам следует подумать о дублировании соответствующих данных, которые вам нужно отобразить, и запрашивать полный документ только при необходимости.
источник
Лучшее, что вы можете сделать, - это не использовать его в
Promise.all
качестве клиента, а затем дождаться.all
чтения, прежде чем продолжить.Итерируйте чтения и позвольте им разрешиться самостоятельно. На стороне клиента это, вероятно, сводится к тому, что в пользовательском интерфейсе несколько изображений загрузчика выполнения разрешаются в значения независимо. Однако это лучше, чем замораживание всего клиента до
.all
разрешения чтения.Следовательно, немедленно выгрузите все синхронные результаты в представление, а затем позвольте асинхронным результатам поступать по мере их разрешения, индивидуально. Это может показаться незначительным различием, но если у вашего клиента плохое подключение к Интернету (как у меня сейчас в этом кафе), замораживание всего клиентского опыта на несколько секунд, скорее всего, приведет к тому, что это приложение отстой.
источник
Promise.all
... он не обязательно должен «замораживать» что-либо - вам может потребоваться дождаться всех данных, прежде чем вы сможете сделать что-то значимое