¿Cómo agrupo por _id y país?
-
11-12-2019 - |
Pregunta
Necesito agrupar por _id y países.He logrado agrupar por _id
, pero me gustaría saber cómo agrupar los países en estos _id
s y devolver el recuento de cada país.
Estoy usando el marco de agregación.Hasta ahora, todo 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']
Los siguientes retornos:
[
[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"
}
]
}
]
Solución
cambié el $group
para concatenar ambos _id
y 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 } },
]
}
Otros consejos
$ grupos grupos documentos juntos con el fin de calcular valores agregados basados en una colección de documentos.Prácticamente, el grupo a menudo admite tareas como las vistas de página promedio para cada página en un sitio web a diario.
La salida de $group depende de cómo defina los grupos.Comience especificando un identificador (es decirun campo _id) para el grupo que está creando con esta tubería.Puede especificar un solo campo de los documentos en la tubería, un valor previamente calculado o una clave agregada compuesta por varios campos entrantes.
Cada expresión de grupo debe especificar un campo _id.Puede especificar el campo _id como una referencia de ruta de campo punteada, un documento con múltiples campos entre llaves (es decir,{ y }), o un valor constante.
Primero intentaría agrupar por _id y país (permitiéndole hacer el recuento que desee), luego agruparía el resultado solo por _id para darle la estructura que desea.
Actualizado:
Estaba pensando en algo como esto..pero no tengo una configuración de entorno para comprobarlo.
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']