sql >> Base de Datos >  >> NoSQL >> MongoDB

Mapa de Mongo Reducir la primera vez

Bien, se me ocurrió algo que creo puede hacer lo que quiera. Tenga en cuenta que esto puede no funcionar exactamente ya que no estoy 100% seguro de su esquema (considerando que sus ejemplos muestran refer disponible en el tipo a, pero no en el b (no estoy seguro de si se trata de una omisión o de lo que desea ver por referencia)... De todos modos, esto es lo que se me ocurrió:

La función de mapa:

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 función Reducir:

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

Básicamente, cómo funciona es así. La función Map usa una clave de refer.url (lo que adiviné según su descripción). Entonces, el resultado final se verá como una matriz con _id igual a refer.url (Se agrupa en base a url). Luego crea un objeto que tiene dos objetos debajo (tipos y etiquetas). El motivo del objeto es que map y reduce puedan emitir el mismo objeto de formato. Aparte de eso, PIENSO que debería explicarse por sí mismo (si no lo entiendes, puedo intentar explicarte más)...

Así que implementemos esto en PHP (suponiendo que $map y $reduce son cadenas con lo anterior contenido con ellas por concisión):

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

Tenga en cuenta que no he probado esto. Esto es justo lo que se me ocurrió en base a mi comprensión de su esquema, y ​​de mi comprensión de Mongo y su implementación Map-Reduce...