komron️
Всем привет. Есть вопрос на счёт дизайна моей базы данных в монге. Если есть мысли, пишите.
Nickolay
Nickolay
Если у одного юзера может быть несколько фильтров, то и их бы бросил отдельно и таким же способом связал
Nickolay
В книге mongo in action хорошо расписано про отношения сущностей в базе, чтиво об отношениях на 15 минут
Алексей
Nickolay
да
komron️
Aʟᴇx
komron️
Nickolay
при текущем дизайне ты будешь делать много запросов с поиском по листам, как ты собираешься индексировать это?
Nickolay
еще глубже объяснено в вышеупомянутой книге
yopp
yopp
тут есть много вариантов
yopp
самый простой сделать понятие «подписка», которая будет включать в себя три параметра: пользователь, фид, фильтры
komron️
yopp
да
yopp
и в зависимости от того, как вы хотите доставлять пользователям обновления, у вас есть разные варианты
yopp
но в любом случае, если у вас будут текстовые фильтры по всему содержимому rss записи, простого решения не будет
yopp
у вас доставка в каком виде происходит?
komron️
yopp
ага
yopp
т.е. у вас задача при появлении нового фида, определить каким пользователям надо отправить сообщение
komron️
komron️
но теперь надо учитывать фильтры
yopp
фильтры у пользователя глобальные или на каждую подписку?
komron️
komron️
на самом деле тут не только rss, но еще и твиттер аккаунты, и т.д.
komron️
komron️
yopp
ага
yopp
я бы вынес подписки в отдельную коллекцию
yopp
и там бы хранил метаданные
komron️
просто все подписки подряд?
yopp
обычно у пользователя меньше подписок, чем у подписок пользователей, а значит в ней стоит групировать подписки по пользователям
yopp
т.е. по отдельному документу на пользователя и туда положить фильтры
yopp
если так-же сделать user_id: …; то в этом случае можно будет легко решить проблему, когда у пользователя очень много подписок и они не влазят в один документ
komron️
а для существующих коллекций надо что-то менять?
komron️
опять таки самым затратным будет обновление ресурсов rss, так что я не очень хочу чтоб я один тот же ресурс брал дважды для отправки пользователю
yopp
что-то в духе
{
_id: ObjectId,
user_id: ...,
filters: [...],
feed_ids: [ObjectId, ObjectId],
count: <feeds.count>
}
дальше индекс по feed_ids и когда вы добавляете новую запись в ленту, то вы в один запрос можете вытащить всех подписанных пользователей. Плюс, в теории, можно сразу отрбасывать пользователей по значению filters.
Но тут надо стеммер с обоих сторон. Сделать частотный анализ статьи, выбрать N самых частых слов, получить для всех слов исходные словоформы и добавит их как условие в запрос.
А при добавлении нового фильтра, в отдельное поле добавлять словоформы фильтров.
yopp
Так можно отбросить часть пользователей сразу, но кроме безобидных ложно-отрицательных срабатываний, могут быть очень обидные ложно-положительные
yopp
но это всё будет зависеть от того как вы хотите фильтровать в принципе
yopp
если по точному совпадению, то можно без словоформ обойтись
yopp
(хотя наверное частотный анализ лучше сразу по словоформам делать)
komron️
так получается поле subscribed в коллекции rss стоит сбросить?
Nickolay
Почему не хранить filter, user и feed в разных коллекциях? это же будет работать намного быстрее. Я год назад переписывал как раз похожий дизайн монги и много времени делалась выборка с листами
komron️
что-то в духе
{
_id: ObjectId,
user_id: ...,
filters: [...],
feed_ids: [ObjectId, ObjectId],
count: <feeds.count>
}
дальше индекс по feed_ids и когда вы добавляете новую запись в ленту, то вы в один запрос можете вытащить всех подписанных пользователей. Плюс, в теории, можно сразу отрбасывать пользователей по значению filters.
Но тут надо стеммер с обоих сторон. Сделать частотный анализ статьи, выбрать N самых частых слов, получить для всех слов исходные словоформы и добавит их как условие в запрос.
А при добавлении нового фильтра, в отдельное поле добавлять словоформы фильтров.
и как я понимаю ObjectId в поле feed_ids тут это reference на документы rss?
komron️
Aʟᴇx
yopp
yopp
komron️
окей, ну тогда при доставке новостей, я буду проходить через каждый документ в rss, и по каждому подписчику буду вытягивать фильтры?
yopp
да
yopp
выбирая между «хранить фильтры у пользователя» и «хранить список подписчиков в фидах вместе с фильтрами», я предлагаю выбрать «завести третью коллекцию с подписками и фильтрами».
это более гибкое решение
yopp
16 мегабайт не так много как кажется
komron️
все стало гораздо понятней 👍
yopp
если сразу использовать паттерн бакет для подписок, и ограничить один документ сотней-другой, то проблем особых не будет
komron️
yopp
https://www.mongodb.com/blog/post/building-with-patterns-the-bucket-pattern
komron️
кстати о третей коллекции, я правильно понимаю что оно будет более короткой версией коллекции users - но теперь с фильтрами и подписками?
yopp
https://www.mongodb.com/blog/post/paging-with-the-bucket-pattern--part-1
yopp
yopp
причём я рекомендую фильтры хранить ещё и у пользователя
yopp
т.е. source of truth это users, а в подписках кешировать значение и обновлять его вместе с обновлением у пользователя
komron️
окей, спасибо большое за вашу помощь!
Алексей
У монги много применений
Разве среди них есть вариант "использовать монгу как реляционную бд"? Можно какой-то Профит получить?
Dmitriy
Добрый день, господа и дамы.
Подскажите, можно ли в запросе приводить один тип к другому? Есть задача взять данные по времени, но время в поле документа сохраненно как строка.
Bohdan
https://docs.mongodb.com/manual/reference/operator/aggregation/dateFromString/
Bohdan
может быть это то что тебе нужно
Dmitriy
Dmitriy
yopp
более того, под «реляционными базами» обычно понимаются табличные хранилища с гарантиями целостности ссылок между записями.
но в реальности такие хранилища очень плохо работают с отношениями, потому ссылки между записями в таблицах позволяют эффективно моделировать только очень небольшой срез систем отношений.
а настоящей «реляционной базой» будет современное графовое хранилище, в котором отношения являются строительным блоком. например neo4j.
Anonymous
Привет.
Распарсил длинный .csv файл в массив объектов.
Существует метод для отправки в Mongo всего массива с последующим сохранением вместо пробегания по массиву и сохранения объектов в БД поштучно?