Как проверить, содержит ли массив две определенные строки в Firestore?

#firebase #nosql #google-cloud-firestore

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

Вопрос:

Я пытаюсь создать приложение для чата, в котором могут быть чаты максимум с двумя пользователями. Я получил документы collection chatrooms и chatroom с полем массива members , которое содержит два идентификатора пользователя. Знаете, прежде чем я смогу создать новую комнату чата, я хочу проверить, есть ли у двух конкретных пользователей уже общая комната чата, поэтому мне нужно запросить два идентификатора пользователя в моих документах.

В конце я просто хочу проверить, существует ли комната чата, а затем вернуть false, а затем попытаться создать другую комнату чата с теми же двумя конкретными идентификаторами пользователя.

Моя проблема заключается в запросе содержимого массива.

Я пытался с

 chatroomsCollection.where('members', '==', firstUserID).where('members', '==', secondUserID).limit(1).get() 
  

и попытался

 chatroomsCollection.where('members','array-contains', firstUserID).where('members', 'array-contains', secondUserID).limit(1).get()
  

но это не работает.

Возможно ли вообще запрашивать несколько строк с элементами внутри массива в NoSQL?

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

1. К вашему сведению, такого языка, как «NoSQL», не существует. То, что вы спрашиваете, относится конкретно к Firestore. Это база данных типа NoSQL, что означает отсутствие реляционных запросов, таких как объединения.

2. Первая попытка завершается неудачей, потому что вы сравниваете элементы массива со строкой идентификатора пользователя. Второй сбой, потому что вы не можете иметь два ‘array-contains’ в одном запросе, смотрите Раздел о составных запросах: firebase.google.com/docs/firestore/query-data/queries

Ответ №1:

Если вы хотите выполнить подобный запрос, вам понадобится другая структура данных. Рассмотрим вместо этого поле типа объекта, подобное этому:

 members: {
    'uid1': true,
    'uid2': true
}
  

Затем вы можете запрашивать документы следующим образом:

 chatroomsCollection
    .where('members.uid1', '==', true)
    .where('members.uid2', '==', true)
    .limit(1)
    .get()
  

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

1. Я согласен, вероятно, это правильный путь.

2. Я уже видел эту структуру в примере, но не был уверен в двух вещах, смогу ли я реализовать ее с помощью этой структуры. 1. Могу ли я по-прежнему использовать array-contains , если я хочу запросить все чаты, участником которых является пользователь? 2. Должен ли я выполнять два отдельных запроса, если порядок строк, переданных в запросе, обратный?

3. @ConstantinBeer 1. Нет, не для объектов. 2. Нет.

4. @DougStevenson Ты мне очень помог и сэкономил много времени. Спасибо!

5. В настоящее время я использую структуру такого рода, но с атрибутами с именами «user1» и «user2», мне нужен запрос, чтобы найти, существует ли документ, содержащий две конкретные строки в разделах «user1» и «user2». Проблема в том, что я не знаю заранее порядок. Итак, пример: у меня есть две входные строки: «Apple» и «Banana», и я хочу проверить, существует ли этот документ — есть два варианта: «user1» = «Apple», «user2» = «Banana» ИЛИ «user1» = «Banana», «user2» = «Apple». Обе эти ситуации допустимы, и я хочу их извлечь. Как бы я написал этот запрос?