o7412369815963
Июль 16, 2010 16:16:21
у меня есть коллекция posts (сообщение/ветка) и users (пользователи), как реализовать систему “не прочитанных сообщений”?
что-б нагрузка на сервер и базу была минимальной.
вариант в лоб:
в коллекции users сделать список не прочитанных веток (users.unread), при изменении ветки обработчик пробегает по всем пользователям и добавляет эту ветку.
при прочтении удаляет ветку из списка users.unread,
каждую ночь запускается скрипт и удаляет ветки из unread которым более недели.
unread можно вынести в отдельную коллекцию.
мне кажется это тормозной вариант, считаю что можно сделать как-то оптимальней.
или наоборот:
сделать posts.readed и закидывать туда пользователей которые прочли ветку, при обновлении ветки список опустошать. в данном методе изменений будет меньше.
так же можно с пользователями: users.readed.
o7412369815963
Июль 16, 2010 16:25:10
пока лидирует вариант с posts.readed, т.к. ветку все равно переписывать, то и список пользователей заодно.
а при прочтении добавлять в posts.readed пользователя и в довесок сделать счетчик просмотров ветки т.к. все равно переписывать.
Lexander
Июль 16, 2010 21:27:41
Если кол-во пользователей небольшое (зависит от железа), то можно хранить данные о прочтении в виде списка. если я правильно понял, то под “списком” ты подразумеваешь “массив” в терминологии МонгоДБ.
При этом, достаточно массива posts.readed.
Операции изменения достаточно легкие для базы: $push или $addToSet (зависит от алгоритма).
Легко получить в том числе и то, что ты собирался получать из users.readed.
Например, список непрочитанных веток можно получить через проверку наличия пользователя в массиве readed, что-то типа:
posts.find({readed: {$not: my_user_id}})
o7412369815963
Июль 17, 2010 01:36:34
что-то $addToSet не робит:
user = db.users.find_one()
post = db.posts.find_one({ '_id':ObjectId('4c40cebb9f1fdf144d000003') })
print post['readed']
db.posts.update({ '_id':ObjectId('4c40cebb9f1fdf144d000003') }, { '$addToSet':{ 'readed':user } } )
пока делаю так:
post['readed'].append(user)
db.posts.save(post)
Lexander
Июль 17, 2010 13:31:56
Уверен, что поле readed правильно создал? У меня из консоли все работает.
G:\Programs\mongodb\bin>mongo
MongoDB shell version: 1.4.4
url: test
connecting to: test
type "exit" to exit
type "help" for help
> db
test
> db.users.insert({name: 'lex'})
> db.users.find()
{ "_id" : ObjectId("4c418357ac3b00000000473e"), "name" : "lex" }
> db.posts.insert({created: new Date('17-07-2010'), author: 'any', readed: []})
> db.posts.find()
{ "_id" : ObjectId("4c41845bac3b00000000473f"), "created" : "Thu Jan 01 1970 02:00:00 GMT+0200", "author" : "any", "readed" : [ ] }
> db.users.insert({name: 'Mr. Second'})
> db.users.find()
{ "_id" : ObjectId("4c418357ac3b00000000473e"), "name" : "lex" }
{ "_id" : ObjectId("4c418492ac3b000000004740"), "name" : "Mr. Second" }
> db.posts.update({"_id" : ObjectId("4c41845bac3b00000000473f")}, {$addToSet: {readed: ObjectId("4c418492ac3b000000004740")}})
> db.posts.find()
{ "_id" : ObjectId("4c41845bac3b00000000473f"), "author" : "any", "created" : "Thu Jan 01 1970 02:00:00 GMT+0200", "readed" : [ ObjectId("4c418492ac3b000000004740") ] }
> db.posts.update({"_id" : ObjectId("4c41845bac3b00000000473f")}, {$addToSet: {readed: ObjectId("4c418357ac3b00000000473e")}})
> db.posts.find()
{ "_id" : ObjectId("4c41845bac3b00000000473f"), "author" : "any", "created" : "Thu Jan 01 1970 02:00:00 GMT+0200", "readed" : [
ObjectId("4c418492ac3b000000004740"),
ObjectId("4c418357ac3b00000000473e")
] }
>
o7412369815963
Июль 17, 2010 13:35:20
возможно не работает из-за того что я добавляю сам объект, а не ид.
ща проверю
o7412369815963
Июль 17, 2010 13:46:34
у меня монга версии 1,2,2, там нет $addToSet
Lexander
Июль 17, 2010 13:50:19
А $push есть?
o7412369815963
Июль 17, 2010 14:03:13
обновил до 1,4,4, теперь добавляет
а зачем нужен ObjectId? только мешает везде.
Lexander
Июль 17, 2010 14:51:27
Это просто тип данных по-умолчанию для _id, аналог GUID.
Его можно заменить на свой, обеспечивающий уникальность для первичного ключа.
В работе он совсем не мешает, например:
> u = db.users.findOne()
{ "_id" : ObjectId("4c418357ac3b00000000473e"), "name" : "lex" }
> print(u['_id'])
4c418357ac3b00000000473e
> post = db.posts.findOne()
{
"_id" : ObjectId("4c41845bac3b00000000473f"),
"author" : "any",
"created" : "Thu Jan 01 1970 02:00:00 GMT+0200",
"readed" : [
ObjectId("4c418492ac3b000000004740"),
ObjectId("4c418357ac3b00000000473e")
]
}
> db.posts.update({_id: post['_id']}, {$pull: {readed: u['_id']}})
> post = db.posts.findOne()
{
"_id" : ObjectId("4c41845bac3b00000000473f"),
"author" : "any",
"created" : "Thu Jan 01 1970 02:00:00 GMT+0200",
"readed" : [
ObjectId("4c418492ac3b000000004740")
]
}
>