sql >> Database >  >> NoSQL >> MongoDB

hoe het aantal en het unieke aantal te berekenen over twee velden in de functie Mongo verminderen

Je kunt eigenlijk een willekeurig object doorgeven aan de tweede parameter van de emit-aanroep. Dat betekent dat u hiervan kunt profiteren en de gebruikers-ID erin kunt opslaan. Uw kaartfunctie kan er bijvoorbeeld als volgt uitzien:

var mapFunc = function() {
  if (this.track_redirect) {
    var tempDoc = {};
    tempDoc[this.track_userid] = 1;

    emit(this.track_redirect, {
      users_clicked: tempDoc,
      total_clicks: 1
    });
  }
};

En je reduceerfunctie kan er als volgt uitzien:

var reduceFunc = function(key, values) {
  var summary = {
    users_clicked: {},
    total_clicks: 0
  };

  values.forEach(function (doc) {
    summary.total_clicks += doc.total_clicks;
    // Merge the properties of 2 objects together
    // (and these are actually the userids)
    Object.extend(summary.users_clicked, doc.users_clicked);
  });

  return summary;
};

De eigenschap user_clicked van het samenvattingsobject slaat in feite de id van elke gebruiker op als een eigenschap (aangezien u geen dubbele eigenschappen kunt hebben, kunt u garanderen dat het unieke gebruikers zal opslaan). Merk ook op dat u voorzichtig moet zijn met het feit dat sommige van de waarden die aan de reduceerfunctie worden doorgegeven, het resultaat kunnen zijn van een eerdere reducering en de bovenstaande voorbeeldcode houdt daar rekening mee. U kunt meer over het genoemde gedrag vinden in de documenten hier .

Om de unieke telling te krijgen, kunt u de finalizer-functie doorgeven die wordt aangeroepen wanneer de reductiefase is voltooid:

var finalFunc = function(key, value) {
  // Counts the keys of an object. Taken from:
  // http://stackoverflow.com/questions/18912/how-to-find-keys-of-a-hash
  var countKeys = function(obj) {
    var count = 0;

    for(var i in obj) {
      if (obj.hasOwnProperty(i))
      {
        count++;
      }
    }

    return count;
  };

  return {
    redirect: key,
    total_clicks: value.total_clicks,
    unique_clicks: countKeys(value.users_clicked)
  };
};

Ten slotte kunt u de taak voor het verkleinen van de kaart als volgt uitvoeren (wijzig het attribuut out om aan uw behoeften te voldoen):

db.users.mapReduce(mapFunc, reduceFunc, { finalize: finalFunc, out: { inline: 1 }});



  1. Hoe kan ik in Mongodb alleen indexeren op veld (en) in verzameling (en) in secundaire knoop (replica-set)

  2. geoNear retourneert onjuiste afstand

  3. De strijd om de NoSQL-databases - MongoDB en Oracle NoSQL vergelijken

  4. Mongoose, zoek, retourneer specifieke eigenschappen