Лента социальной активности - лучший подход для ограниченных коллекций в MongoDB?

Я работаю над системой подачи социальной активности, очень похожей на 10Gen Socialite Project, который запущен в производство уже несколько лет. У меня есть новый вариант использования, в котором мне нужно хранить хронологически упорядоченный список действий для пользователя, где список действий должен:

  1. содержит только последние вставленные N элементов
  2. не вставлять дубликаты семантически эквивалентных элементов
  3. позволяют просматривать результаты.

До сих пор я придумал два подхода к решению этой проблемы, но оба, кажется, имеют неприятные ограничения.

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

{
    "owner": {
      "type": "user",
      "id" : "1234"
    },
    "activity": {
        "published": "2013-09-27T17:08:26+00:00",
        "actor": {
            "type": "elastic-search-node",
            "id": "2"
        },
        "verb": "recommend",
        "object": {
            "type": "review",
            "id": "1093773"
        }
        "uuid": "6d70eaa4-0766-4949-971d-98740cb9eca1"
    }
}

Каждый раз, когда я получаю новое действие для данного пользователя, я вставляю документ, как указано выше, с тем же условием "владелец", но с другим предложением "действие". Однако я не уверен в самом эффективном способе обработки моих вкладышей. Учитывая критерии выше, один подход псевдокода будет:

results = collection.update(
  {
    'owner.id':'1234', 
    'activity.verb':'recommend',
    'activity.object.type':'review',
    'activity.object.id':'1093773'
  },
  the_activity,
  upsert:true)

# count documents for owner.id = 1234
# if count > max_documents, delete oldest document

Проблема этого подхода состоит в том, что для завершения вставки и удаления может потребоваться до 3 операций с базой данных. Тем не менее, использование 'upsert' заботится о предотвращении дубликатов, и мы можем использовать сгенерированный ObjectID для временных запросов и разбиения на страницы.

Другой подход, на который я смотрел, похож на подход FanoutOnWriteSizedBuckets в Socialite. В этом случае список действий сохраняется в массиве максимального размера в качестве поддокумента, индексируемого по идентификатору пользователя. Например:

{
    "owner" : {"type":"user", "id":"1234"},
    "feed" : [
        {"_id" : ObjectId("...da7"), "activity" : ...},
        {"_id" : ObjectId("...dc1"), "activity" : ...},
        {"_id" : ObjectId("...dd2"), "activity" : ...}
    ]
}

В этом случае запросы также довольно просты, но, опять же, вставки проблематичны. Я рассмотрел использование различных методов и комбинаций $update, $push, $addToSet, $ne, $each и т. Д., Но ни один из них, по-видимому, не в состоянии обеспечить более эффективное предотвращение дублирования операций вставки и удаления, чем выше.

Кто-нибудь может предложить подход для решения этого варианта использования?

Спасибо!

(x-отправлено в группу пользователей mongodb)РЕШЕНО: https://groups.google.com/forum/

0 ответов

Другие вопросы по тегам