Модель данных MongoDB для поддержки уникальных посетителей, по событию, по диапазону дат

У меня есть несколько веб-сайтов, на каждом из которых есть посетители, которые «вызывают» несколько событий, которые я хочу отслеживать. У меня есть журнал этих событий со всех веб-сайтов, каждое событие заполнено идентификатором веб-сайта, именем события и идентификатором пользователя, который выполнил событие (для простоты, скажем так).

Требования:

  1. Иметь возможность получить по идентификатору веб-сайта и названию события, сколько уникальных посетителей его получили.
  2. Это также должно поддерживать диапазон дат (отдельные уникальные посетители в диапазоне).

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

collection ev_{websiteId}:
[
    {
        _id: "error"
        dailyStats: [
            {
                _id: 20121005 <-- (yyyyMMdd int, should be indexed!)
                hits: 5
                users: [ 
                         {
                            _id: 1, <-- should be indexed!
                            hits: 1
                         }, 
                         {
                            _id: 2
                            hits: 3
                         },
                         {
                            _id: 3,
                            hits: 1
                         }
                ]
            },
            {
                _id: 20121004 
                hits: 8
                users: [ 
                         {
                            _id: 1,
                            hits: 2
                         }, 
                         {
                            _id: 2
                            hits: 3
                         },
                         {
                            _id: 3,
                            hits: 3
                         }
                ]
            },
        ]
    },
    {
        _id: "pageViews"
        dailyStats: [
            {
                _id: 20121005 
                hits: 500
                users: [ 
                         {
                            _id: 1, 
                            hits: 100
                         }, 
                         {
                            _id: 2
                            hits: 300
                         },
                         {
                            _id: 3,
                            hits: 100
                         }
                ]
            },
            {
                _id: 20121004
                hits: 800
                users: [ 
                         {
                            _id: 1, 
                            hits: 200
                         }, 
                         {
                            _id: 2
                            hits: 300
                         },
                         {
                            _id: 3,
                            hits: 300
                         }
                ]
            },
        ]
    },
]

Я использую _id для хранения идентификатора события. Я использую dailyStats._id для хранения, когда это произошло (целое число в формате ггггММдд). Я использую dailySattes.users._id для представления хеша уникального идентификатора пользователя.

Чтобы получить уникальных пользователей, я в основном должен иметь возможность запускать (сократить?) количество элементов в массиве (массивах) для определенного диапазона дат (я преобразую диапазон дат в ггггММдд).

Мои вопросы:

  1. эта модель данных имеет смысл для вас? Меня беспокоит масштабируемость этой модели с течением времени (если у меня много ежедневных уникальных посетителей в каком-то клиенте, это приводит к огромному документу). Я думал об удалении документов dailyStats по _id ‹ [дата в формате ггггММдд]. Таким образом, я могу сохранить размер своих документов в разумных пределах, но, тем не менее, здесь есть ограничения.
  2. Есть ли простой способ запустить «upsert», который также создаст dailyStats, если он еще не создан, добавит пользователя, если он еще не создан, и увеличит свойство «hits» для обоих?
  3. как насчет уменьшения карты? как бы вы подошли к этому (необходимо запускать отдельные пользователи._id для всех вложенных документов в заданном диапазоне дат)? есть ли более простой способ с новой структурой агрегации?

Кстати, еще один вариант решения проблем с уникальными посетителями — использование растровых изображений Redis, но я не уверен, что стоит хранить несколько хранилищ данных (с точки зрения обслуживания).


person Oren Ellenbogen    schedule 24.10.2012    source источник


Ответы (1)


Несколько комментариев к текущей выше архитектуре.

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

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

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

{
  "_id":"20121005_siteKey_page",
  "hits":512,
  "users":[
   {
     "uid":5, 
     "hits":512,
   }
}

Таким образом, вы ограничиваете размеры своих документов чем-то, что будет разумным для быстрой вставки. Отсюда вы можете выполнять задания mapreduce партиями, чтобы еще больше расширить то, что вы хотите увидеть.

Это также зависит от вашей конечной цели. Вы хотите предоставить показатели в реальном времени? Какую степень детализации вы пытаетесь получить? Redis Maps может быть тем, на что вы хотите хотя бы взглянуть: отличная статья здесь.

Тем не менее, это забавная проблема для решения :)

Надеюсь, это помогло!

person Petrogad    schedule 24.10.2012