Моделирование данных Firestore для библиотечных книг + данные списка пожеланий - PullRequest
0 голосов
/ 30 марта 2020

Я работаю над приложением библиотеки и использую Firestore со следующими (упрощенными) двумя коллекциями books и wishes:

Book
- locationIds[] # Libraries where the book is in stock

Wish
- userId # User who has wishlisted a book
- bookId # Book that was wishlisted

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

Я могу представить два способа решения этой проблемы:

ПОДХОД 1

Скопируйте массив locationIds[] на каждый Wi sh, содержащий идентификаторы каждого местоположения, имеющего копию этой книги.

Тогда мой запрос будет (псевдокод):

collection('wishes')
.where('userId' equals myUserId)
.where('locationIds' contains myLocationId)

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

APPROACH 2

Добавьте массив wishers[] к каждой книге, содержащий идентификаторы каждого пользователя, который внес ее в список.

Тогда запрос будет выглядеть примерно так:

collection('books')
.where('locationIds' contains myLocationId)
.where('wishers' contains myUserId)

Проблема с это значит, что массив wishers для конкретной книги может вырасти довольно большим (я хотел бы поддержать тысячи пожеланий для каждой книги), и тогда это станет беспорядком.

Требуется помощь

На мой взгляд, ни один из этих подходов не идеален. Если бы мне пришлось выбрать один, я, вероятно, go с подходом 1 просто потому, что я не хочу, чтобы мой объект Book содержал такой огромный массив.

Я уверен, что я не первый, кто сталкивается с такой проблемой, есть ли лучший способ?

1 Ответ

1 голос
/ 30 марта 2020

Вы можете попробовать разделить запрос на два разных запроса. Например, в псевдокоде:

wishes = db.collection('wishes').where('userId', '==', myUserId)
book_ids = [wish.bookId for wish in wishes]
books = db.collection('books').where('bookId', 'in', book_ids)
result = [book.bookId for book in books if book.locationIds]

Обратите внимание, что это всего лишь пример, этот код, вероятно, не работает, так как я не проверял его, а клавиатура in просто поддерживает 10 значения . Но Вы получаете идею. Хорошей идеей будет добавление длины locationIds или ее пустого значения в отдельном атрибуте, чтобы вы могли пропустить последнюю итерацию, запрашивая книги с помощью:

books = db.collection('books').where('bookId', 'in', book_ids).where('hasLocations', '==', True)

Хотя вам все равно придется итерируйте, чтобы получить только bookId.

Кроме того, вам следует избегать использования массивов в Firestore, поскольку он не имеет встроенной поддержки для них, как объяснено в их блоге .

Обязательно ли использовать номер SQL? Может быть, вы могли бы сделать это отношение M: M лучше в SQL. Имейте в виду, что я не эксперт по базам данных.

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