Question

Je dois regrouper par _id et pays.J'ai réussi à regrouper par _id, mais j'aimerais savoir comment regrouper les pays dans ces _ids et renvoie le décompte pour chaque pays.

J'utilise le framework d'agrégation.Jusqu'ici, tout va bien.

conn = Mongo::Connection.new
db   = conn['foobar_development']

cmd = {
  aggregate: 'live_daily_stats',
  pipeline: [
    { '$project' => {
      :metacontent => 1,
      :visits => 1,
    } },
    { '$unwind' => '$visits' },
    { '$match' => { 'visits.minute' => { '$gt' => 224 } } },
    { '$sort' => { 'visits.minute' => 1 } },
    { '$group' => { 
      :_id => '$_id', 
      :visits => { '$push' => '$visits' }, 
      :visits_count => { '$sum' => 1 },
      :metacontent => { '$addToSet' => '$metacontent' },
      } 
    },
    { '$sort' => { 'visits_count' => -1 } },
  ]
}

res = db.command(cmd)['result']

Les retours suivants :

[
    [0] {
                 "_id" => "20120726/foobar/song/custom-cred",
              "visits" => [
            [0] {
                                              "country_name" => "UK",
                               "iso_two_letter_country_code" => "UK",
                                                   "referer" => "http://localhost:3000/",
                                                    "minute" => 59,
                                                  "token_id" => "134326199711wfryhpdq"
            },
            [1] {
                                              "country_name" => "UK",
                               "iso_two_letter_country_code" => "UK",
                                                   "referer" => "http://localhost:3000/",
                                                    "minute" => 59,
                                                  "token_id" => "134326199711wfryhpdq"
            },
            [2] {
                                              "country_name" => "US",
                               "iso_two_letter_country_code" => "US",
                                                   "referer" => "http://localhost:3000/",
                                                    "minute" => 59,
                                                  "token_id" => "134326199711wfryhpdq"
            }
        ],
        "visits_count" => 1,
         "metacontent" => [
            [0] {
                                     "date" => "20120726"
            }
        ]
    },
    [1] {
                 "_id" => "20120725/foobar/song/test-pg3-long-title-here-test-lorem-ipsum-dolor-lo",
              "visits" => [
            [0] {
                                              "country_name" => "UK",
                               "iso_two_letter_country_code" => "UK",
                                                   "referer" => "http://localhost:3000/",
                                                    "minute" => 58,
                                                  "token_id" => "13432600883knjzcbic"
            }
        ],
        "visits_count" => 1,
         "metacontent" => [
            [0] {
                                     "date" => "20120725"
            }
        ]
    }
]
Était-ce utile?

La solution

j'ai changé le $group concaténer les deux _id et country_name:

cmd = {
  aggregate: 'live_daily_stats',
  pipeline: [
    { '$project' => {
      :metacontent => 1,
      :visits => 1,
    } },
    { '$unwind' => '$visits' },
    { '$match' => { 'visits.minute' => { '$gt' => 224 } } },
    { '$sort' => { 'visits.minute' => 1 } },
    { '$group' => { 
      :_id => { '$add' => ['$_id', '$visits.country_name']}, 
      :visits => { '$push' => '$visits' }, 
      :visits_count => { '$sum' => 1 },
      :metacontent => { '$addToSet' => '$metacontent' },
      } 
    },
    { '$sort' => { 'visits_count' => -1 } },
  ]
}

Autres conseils

Depuis La documentation

$group Regroupe les documents dans le but de calculer Valeurs agrégées basées sur un ensemble de documents.Pratiquement prend souvent en charge des tâches telles que le nombre moyen de pages vues pour chaque page dans un site web au quotidien.

Le résultat de $group dépend de la façon dont vous définissez les groupes.Commencez par en spécifiant un identificateur (c.-à-d.un champ _id) pour le groupe dans lequel vous vous trouvez création à l’aide de ce pipeline.Vous pouvez spécifier un seul champ à partir de l’icône documents dans le pipeline, une valeur précédemment calculée ou un Clé d’agrégation composée de plusieurs champs entrants.

Chaque expression de groupe doit spécifier un champ _id.Vous pouvez spécifier l’attribut _id champ en tant que référence de chemin de champ en pointillés, un document avec plusieurs champs entre accolades (c.-à-d.{ et }), ou une valeur constante.

J'essaierais d'abord de regrouper à la fois par _id et par pays (vous permettant de faire le décompte que vous souhaitez), puis de regrouper le résultat uniquement par _id pour donner la structure souhaitée.

Mis à jour:

Je pensais à quelque chose comme ça..mais je n'ai pas de configuration d'environnement pour le vérifier.

    conn = Mongo::Connection.new
    db   = conn['foobar_development']

    cmd = {
      aggregate: 'live_daily_stats',
      pipeline: [
        { '$project' => {
          :metacontent => 1,
          :visits => 1,
        } },
        { '$unwind' => '$visits' },
        { '$match' => { 'visits.minute' => { '$gt' => 224 } } },
        { '$sort' => { 'visits.minute' => 1 } },
        { '$group' => { 
          :_id => {'$_id','$visits.iso_two_letter_country_code'},
          :page_id => '$_id',
          :visits_count => { '$sum' => 1 },
   .... whatever you want ...
          :metacontent => { '$addToSet' => '$metacontent' },
          } 
        },
        { '$group' => { 
          :_id => '$page_id', 
   .... whatever you want ...
          } 
        },
        { '$sort' => { 'visits_count' => -1 } },
      ]
    }

    res = db.command(cmd)['result']
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top