sql >> Database >  >> NoSQL >> MongoDB

Mongo-kaart Eerste keer verminderen

Oké, ik heb iets bedacht waarvan ik denk kan doen wat je wilt. Houd er rekening mee dat dit mogelijk niet precies werkt, aangezien ik niet 100% zeker ben van uw schema (gezien uw voorbeelden refer beschikbaar in type a, maar niet b (ik weet niet zeker of dat een omissie is, of wat je wilt bekijken door verwijzer)... Hoe dan ook, hier is wat ik heb bedacht:

De kaartfunctie:

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

De functie Verminderen:

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

Dus eigenlijk, hoe het werkt is dit. De kaartfunctie gebruikt een sleutel van refer.url (wat ik vermoedde op basis van uw beschrijving). Het eindresultaat ziet er dus uit als een array met _id gelijk aan refer.url (Het groepeert op basis van url). Vervolgens wordt een object gemaakt met twee objecten eronder (typen en tags). De reden voor het object is dat map en reduce hetzelfde formaatobject kunnen uitzenden. Afgezien daarvan DENK ik dat het relatief duidelijk zou moeten zijn (als je het niet begrijpt, kan ik proberen meer uit te leggen)...

Laten we dit dus in PHP implementeren (ervan uitgaande dat $map en $reduce zijn strings met het bovenstaande erbij voor de beknoptheid):

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

Let op, ik heb dit niet getest. Dit is precies wat ik heb bedacht op basis van mijn begrip van uw schema en van mijn begrip van Mongo en de implementatie van Map-Reduce...



  1. MEAN Stack Bestandsuploads

  2. Hoe de Laravel-website te verbinden met mongoDB-atlas

  3. MongoError:filterparameter moet een object zijn

  4. Maak een notitie-app voor Android met MongoDB Stitch