sql >> Databasteknik >  >> NoSQL >> MongoDB

hur man beräknar antal och unikt antal över två fält i mongo reduceringsfunktion

Du kan faktiskt skicka ett godtyckligt objekt på den andra parametern i emit-anropet. Det betyder att du kan dra nytta av detta och lagra användar-id i det. Till exempel kan din kartfunktion se ut så här:

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

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

Och din reduceringsfunktion kan se ut så här:

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

Egenskapen users_clicked för summary-objektet lagrar i princip varje användares id som en egenskap (eftersom du inte kan ha dubbletter av egenskaper kan du garantera att den lagrar unika användare). Observera också att du måste vara försiktig med att vissa av värdena som skickas till reduceringsfunktionen kan vara resultatet av en tidigare reducering och exempelkoden ovan tar hänsyn till det. Du kan hitta mer om nämnda beteende i dokumenten här .

För att få den unika räkningen kan du passera in finaliseringsfunktionen som anropas när reduceringsfasen är klar:

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

Slutligen kan du utföra kartminskningsjobbet så här (ändra ut-attributet för att passa dina behov):

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



  1. Vad är ett bättre tillvägagångssätt för att lagra och söka efter ett stort dataset med meteorologiska data

  2. Sök efter element i ett objekt i en array

  3. Hur man ställer in utgångsdatum till flera nycklar i Redis

  4. Morphia List<Map<String,Object>>> return Inbäddat element är inte ett DBO-objekt vid sökoperation