Фильтрация по нескольким полям с помощью Firestore - PullRequest
0 голосов
/ 30 октября 2019

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

Collection: Room
   - Document#1
      - query_role: Array - Limit 10
      - query_user: Array - Limit 10
      - players: Array<Object> [{
             playerId: string
             user: Object<id, firstname, lastname, ...>
             role: Object<id, name, ...>
         }]
      ...

В моем приложении есть страница с именами комнат, которую любой может использовать для поиска (как вы уже догадались) комнат.

С фильтрами, чтобы сузить тип комнаты, в которую они могут войти, но для этого примера мы просто будем использовать роль в качестве единственного фильтра. Я просто подумал.

Логика, лежащая в основе страницы поиска / фильтра:

  1. Найти все комнаты, в которых еще есть место
  2. ИспользоватьФильтр для поиска комнат, в которых все еще есть определенная роль (например, Мафия, Доктор, Сельский житель и т. д.), которые не назначены никаким пользователям
Collection: Room
   - Document#1
      - query_role: ['111', '222', '333', '333']
      - query_user: ['user1', 'user2', 'user3', false, false, false, false, false, false, false]
      - players: [{
             playerId: 'djs123d21sSd213r'
             user: null
             role: {
                id: '111',
                value: 'Mafia'
                ...                
             },
             ...
         }]
      ...

Каждая создаваемая рольдля этой комнаты вставляется players->role с пользователем, установленным на null. Затем роль вставляется в query_roles для использования в качестве фильтра на странице, если пользователь выбирает поиск по доступным ролям:

.where('query_roles', 'array-contains', role)

Теперь проблема заключается в пожарном хранилище. Вы можете использовать array-contains только один раз в запросе. Я продолжаю получать ошибки, подобные этой: A maximum of 1 \'ARRAY_CONTAINS\' filter is allowed.'. Другой array-contains, как я упоминал ранее, используется на query_users для поиска комнат, в которых еще есть место, путем:

.where('query_user`, 'array-contains', false)

Я не могу поместить их в объект, подобный так:

{
 user1: true,
 user2: true,
 false: true,
 false :true
}

, так как все эти false будут шлепаться в одно поле, и это будет то же самое с ролями. Поскольку может быть несколько одинаковых ролей, оно объединится в одно поле.

Единственный способ, о котором я могу подумать, - это вручную установить флаг с надписью full: true|false, который будет использоваться для определения, является ликомната заполнена или нет. Мне все еще нужно было бы использовать query_user, потому что в приложении я использую его для поиска всех комнат, в которых находится конкретный пользователь.

Я пишу, чтобы увидеть, есть ли альтернативные способы, которые кто-либо еще может придуматьбез возиться с созданием флагов. Длинный вопрос, но я ценю, что вы читаете до здесь.

1 Ответ

1 голос
/ 30 октября 2019

Найдите все комнаты, в которых еще есть место

Чтобы решить эту проблему, вы можете просто добавить в свой документ комнаты два новых свойства. Один будет назван numberOfRoles, а другой numberOfUsers. Когда вы добавляете новую роль в массив query_role, увеличивайте значение numberOfRoles на единицу, а каждый раз, когда вы добавляете нового пользователя в массив query_user, увеличивайте значение numberOfUsers на единицу. Таким образом, вы можете просто запросить вашу коллекцию комнат, используя:

roomsRef.where('numberOfRoles', '<=', 10).where('numberOfUsers', '<=', 10)

Изменение нескольких функций array-contains не разрешено в Coud Firestore, но объединение в цепочку нескольких вызовов where() будет работать отлично.

Используйте фильтр, чтобы найти комнаты, в которых все еще есть определенная роль (например, Мафия, Доктор, Сельский житель и т. Д.), Которые не назначены никаким пользователям

После того, как выполучить положительный результат от вышеупомянутого запроса, затем вы можете получить содержимое вашего query_role массива и просмотреть доступные списки.

Каждая роль, созданная для этой комнаты, вставляется в игроков->роль с пользователем, установленным на null.

В этом больше нет необходимости.

Единственный способ, о котором я могу думать, - это вручную установить флаг, который говоритfull: true | false, который будет использоваться для определения, заполнена ли комната или нет. Мне все еще нужно использовать query_user, потому что в приложении я использую его для поиска всех комнат, в которых находится конкретный пользователь.

Установка флага на true|false не решит всю вашу проблему. Обратите внимание, что если вы хотите найти конкретного пользователя в массиве query_user, вы все равно можете это сделать, поскольку вы выполняете только один запрос с использованием оператора array-contains.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...