Карта Монго Уменьшить в первый раз

Впервые сопоставьте/уменьшите пользователя здесь и используя MongoDB. У меня есть много данных о посещении страниц, которые я хотел бы понять с помощью Map/Reduce. Ниже в основном то, что я хочу сделать, но, как новичок в Map/Reduce, я думаю, что это выше моих знаний!

  1. Пройдитесь по всем страницам с посещениями за последние 30 дней, где внешние = true.
  2. Затем для каждой страницы найдите все посещения.
  3. Сгруппировать все посещения по реферальному местоположению
  4. Для каждой реферальной локации подсчитайте, сколько потом пошли на страницу, имеющую определенный «тип», а также имеющую определенное слово в «тегах».

База данных и коллекция организованы как

$mongo->dbname->visits

Образец документа такой:

{"url": "www.example.com", "type": "a", "refer": {"external": true, "domain": "twitter.com", "url": "http://www.twitter.com/page"}, "page": "1235", "user": "1232", "time": 1234567890}

А потом я хочу найти документы типа Б с определенным тегом.

{"url": "www.example.com", "type": "b", "page": "745", "user": "1232", "time": 1234567890, "tags": {"a", "b", "c"}}

Я использую обычное расширение Mongo PHP, если это имеет значение.


person James    schedule 09.06.2010    source источник
comment
Какая структура базы данных у вас есть? Как организованы ваши коллекции и документы?   -  person Emil Vikström    schedule 09.06.2010
comment
Добавил в пост выше. Эта помощь?   -  person James    schedule 09.06.2010
comment
Хорошо, ваш образец документа не содержит поля реферала, внешнего или тегов. То, что вы предлагаете, действительно сложно, поэтому вам, вероятно, придется показать нам более одного документа. И вам, вероятно, нужно будет показать его со всеми деталями.   -  person Gates VP    schedule 10.06.2010
comment
Я работаю над чем-то точно таким же, как это (отслеживание посещений с использованием монго), опубликуйте еще несколько деталей, и я, возможно, смогу помочь.   -  person Dal Hundal    schedule 10.06.2010
comment
Обновлено, это предоставляет больше информации для вас, ребята? Спасибо   -  person James    schedule 10.06.2010
comment
Когда вы говорите «Группировать все посещения по реферальному местоположению», что именно вы имеете в виду? То же самое и с №4 (посчитайте, сколько тогда перешло на страницу с определенным типом и определенным словом в тегах)...? Не могли бы вы предоставить небольшой набор данных и ожидаемый результат от этого набора данных (достаточно 4 или 5 строк)?   -  person ircmaxell    schedule 16.06.2010
comment
Вы должны отметить ответ, если он достаточен.   -  person aehlke    schedule 10.08.2010


Ответы (2)


Хорошо, я придумал кое-что, что, думаю, может сделать то, что вы хотите. Обратите внимание, что это может работать не совсем точно, поскольку я не уверен на 100% в вашей схеме (учитывая, что ваши примеры показывают, что refer доступен в типе a, но не b (я не уверен, является ли это упущением или тем, что вы хотите просмотр по рефереру)... Во всяком случае, вот что я придумал:

Функция карты:

function() {
    var obj = {
        "types": {},
        "tags": {},
    }
    obj.types[this.type] = 1;
    if (this.tags) {
        for (var tag in this.tags) {
            obj.tags[this.tags[tag]] = 1;
        }
    }
    emit(this.refer.url, obj);
}

Функция уменьшения:

function(key, values) {
    var obj = {
        "types": {},
        "tags": {},
    }
    for (var i = 0; i < values.length; i++) {
        for (var type in values[i].types) {
            if (!type in obj.types) {
                obj.types[type] = 0;
            }
            obj.types[type] += values[i].types[type];
        }
        for (var tag in values[i].tags) {
            if (!tag in obj.tags) {
                obj.tags[tag] = 0;
            }
            obj.tags[tag] += values[i].tags[tag];
        }
    }
    return obj;
}

Итак, в основном, как это работает. Функция Map использует ключ refer.url (о чем я догадался, основываясь на вашем описании). Таким образом, конечный результат будет выглядеть как массив с _id, равным refer.url (он группируется на основе URL-адреса). Затем он создает объект, под которым находятся два объекта (типы и теги). Причина для объекта заключается в том, что карта и сокращение могут создавать один и тот же объект формата. Кроме этого, я ДУМАЮ, что это должно быть относительно понятно (если вы не понимаете, я могу попытаться объяснить больше)...

Итак, давайте реализуем это на PHP (предполагая, что $map и $reduce являются строками, в которых для краткости содержится указанное выше):

$mapFunc = new MongoCode($map);
$reduceFunc = new MongoCode($reduce);
$query = array(
    'time' => array('$gte' => time() - (60*60*60*24*30)),
    'refer.external' => true
);
$collection = 'visits';
$command = array(
    'mapreduce' => $collection,
    'map' => $mapFunc,
    'reduce' => $reduceFunc,
    'query' => $query,
);

$statsInfo = $db->command($command);

$statsCollection = $db->selectCollection($sales['result']);

$stats = $statsCollection->find();

foreach ($stats as $stat) {
    echo $stats['_id'] .' Visited ';
    foreach ($stats['value']['types'] as $type => $times) {
        echo "Type $type $times Times, ";
    }
    foreach ($stats['value']['tags'] as $tag => $times) {
        echo "Tag $tag $times Times, ";
    }
    echo "\n";
}

Обратите внимание, я не проверял это. Это именно то, что я придумал, основываясь на моем понимании вашей схемы и на моем понимании Mongo и его реализации Map-Reduce...

person ircmaxell    schedule 16.06.2010
comment
$statsCollection = $db-›selectCollection($sales['результат']); $ продаж? - person Toby; 13.07.2011

Сокращение карты уже реализовано в Mongo DB ODM:

http://www.doctrine-project.org/docs/mongodb_odm/1.0/en/reference/map-reduce.html

person hamczu    schedule 15.03.2011