Como posso grupo por _id e do país?
-
11-12-2019 - |
Pergunta
Eu preciso de grupo por _id e países.Eu consegui grupo _id
, mas gostaria de saber como grupo de países em que estas _id
s e retornar a contagem para cada país.
Eu estou usando a agregação quadro.Tão longe, tão bom.
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']
Os seguintes 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"
}
]
}
]
Solução
Eu mudei o $group
para concatenar tanto _id
e 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 } },
]
}
Outras dicas
A partir de a documentação
$grupo Grupos de documentos juntos para a finalidade de calcular agregação de valores com base em uma coleção de documentos.Praticamente, grupo de suporte muitas vezes tarefas, tais como a média de visualizações de página para cada página um site em uma base diária.
A saída de us $grupo depende de como você define grupos.Comece especificar um identificador (por exemplo,um campo _id) para o grupo que você está criar com este pipeline.Você pode especificar um único campo da documentos em pipeline, um valor calculado anteriormente, ou uma agregação de chave composta de vários campos de entrada.
Cada grupo de expressão deve especificar um campo _id.Você pode especificar o _id campo como um pontilhado campo de referência de caminho, um documento com vários campos entre chaves (i.e.{ e }), ou um valor constante.
Eu ia tentar agrupar por tanto _id e o primeiro do país (permitindo que você faça a conta que você deseja) e, em seguida, o grupo o resultado acabou por _id para dar a estrutura que você quer.
Atualizado:
Eu estava pensando em algo assim..mas eu não tenho um env programa de configuração para verificar isso..
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']