MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Mongo Map Réduire la première fois

Ok, j'ai trouvé quelque chose que je pense pouvez faire ce que vous voulez. Notez que cela peut ne pas fonctionner exactement car je ne suis pas sûr à 100 % de votre schéma (considérant que vos exemples montrent refer disponible dans le type a, mais pas b (je ne sais pas si c'est une omission, ou ce que vous voulez voir par référent)... Quoi qu'il en soit, voici ce que j'ai trouvé :

La fonction carte :

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);
}

La fonction Réduire :

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;
}

Donc, fondamentalement, comment cela fonctionne est-ce. La fonction Map utilise une clé de refer.url (ce que j'ai deviné en fonction de votre description). Ainsi, le résultat final ressemblera à un tableau avec _id égal à refer.url (Il regroupe en fonction de l'url). Il crée ensuite un objet qui a deux objets sous lui (types et balises). La raison de l'objet est que map et reduce puissent émettre le même objet de format. A part ça, je PENSE que ça devrait être relativement explicite (si vous ne comprenez pas, je peux essayer d'expliquer plus)...

Alors implémentons ceci en PHP (en supposant que $map et $reduce sont des chaînes avec ce qui précède contenu avec eux pour le laconisme):

$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";
}

Attention, je n'ai pas testé. C'est exactement ce que j'ai trouvé sur la base de ma compréhension de votre schéma et de ma compréhension de Mongo et de son implémentation Map-Reduce...