MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Mongo Map Reduce за първи път

Добре, измислих нещо, което мисля може да прави каквото иска. Имайте предвид, че това може да не работи точно, тъй като не съм 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...



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB $dateFromParts

  2. mongoose, за да определи, че update-upsert прави вмъкване или актуализиране

  3. Елемент на масив за актуализиране на документ MongoDB с помощта на метода findOneAndUpdate в Java

  4. mongo копие от една колекция в друга (в същия db)

  5. Кеширане на повтарящи се резултати от заявки в MongoDB