MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Melhorias na estrutura de agregação do MongoDB 2.6

Este é um post convidado de Vlad Mihalcea. Vlad é um arquiteto de software apaixonado por integração de software, alta escalabilidade e desafios de simultaneidade. Aqui está um link para o post original.

O MongoDB está evoluindo rapidamente. A versão 2.2 introduziu a estrutura de agregação como uma alternativa ao modelo de consulta Map-Reduce. Gerar relatórios agregados é um requisito recorrente para sistemas corporativos e o MongoDB se destaca nesse aspecto. Se você é novo nisso, confira esta introdução da estrutura de agregação ou o ajuste de desempenho e os guias de modelagem de dados.

Vamos reutilizar o modelo de dados que apresentei pela primeira vez ao demonstrar os recursos de inserção extremamente rápidos do MongoDB:

{ "_id":ObjectId("5298a5a03b3f4220588fe57c"), "created_on":ISODate("2012-04-22T01:09:53Z"), "value":0.1647851116706831}

Aprimoramentos de agregação do MongoDB 2.6


Na versão 2.4, se eu executar a seguinte consulta de agregação:
db.randomData.aggregate( [{ $match:{ "created_on" :{ $gte :new Date(Date.UTC(2012, 0, 1)), $lte :new Date(Date.UTC(2012, 0, 10)) } }},{ $grupo:{ _id:{ "minuto":{ $minuto:"$criado_on" } }, "valores":{ $addToSet:"$valor" } }}]); 

Eu atingi a limitação de resultado de agregação de 16 MB:
{ "errmsg":"exceção:o resultado da agregação excede o tamanho máximo do documento (16 MB)", "code":16389, "ok":0}

Os documentos do MongoDB são limitados a 16 MB e, antes da versão 2.6, o resultado da agregação era um documento BSON. A versão 2.6 o substituiu por um cursor.

Executar a mesma consulta na versão 2.6 produz o seguinte resultado:

db.randomData.aggregate( [{ $match:{ "created_on" :{ $gte :new Date(Date.UTC(2012, 0, 1)), $lte :new Date(Date.UTC(2012, 0, 10)) } }},{ $grupo:{ _id:{ "minuto":{ $minuto:"$criado_on" } }, "valores":{ $addToSet:"$valor" } }}]). objsLeftInBatch();14

Usei o método objsLeftInBatch baseado em cursor para testar o tipo de resultado de agregação, e a limitação de 16 MB não se aplica mais ao resultado geral. Os resultados internos do cursor são documentos BSON regulares, portanto, eles ainda estão limitados a 16 MB, mas isso é muito mais gerenciável do que o limite de resultado geral anterior.

A versão 2.6 também aborda as restrições de memória de agregação. Uma verificação de coleção completa, como:

db.randomData.aggregate( [{ $grupo:{ _id:{ "minuto":{ $minuto:"$criado_on" } }, "valores":{ $addToSet:"$valor" } }}]) .objsLeftInBatch();

pode acabar com o seguinte erro:
{ "errmsg" :"exceção:limite de memória excedido para $group, mas não permitiu classificação externa. Passe allowDiskUse:true para ativar.", "code" :16945, "ok" :0} 
Assim, agora podemos realizar grandes operações de classificação usando o parâmetro allowDiskUse:
db.randomData.aggregate( [{ $grupo:{ _id:{ "minuto":{ $minuto:"$criado_on" } }, "valores":{ $addToSet:"$valor" } }}], { allowDiskUse :true}).objsLeftInBatch();

A versão 2.6 nos permite salvar o resultado da agregação em uma coleção diferente usando o estágio $out recém-adicionado.
db.randomData.aggregate( [{ $match:{ "created_on" :{ $gte :new Date(Date.UTC(2012, 0, 1)), $lte :new Date(Date.UTC(2012, 0, 10)) } }},{ $group:{ _id :{ "minuto" :{ $minuto :"$criado_on" } }, "valores":{ $addToSet:"$valor" } }},{ $ out :"randomAggregates"}]);db.randomAggregates.count();60

Novos operadores foram adicionados, como let, map, cond, para citar alguns.

O próximo exemplo anexará AM ou PM às informações de tempo de cada entrada de evento específica.
var dataSet =db.randomData.aggregate( [{ $match:{ "created_on" :{ $gte :new Date(Date.UTC(2012, 0, 1)), $lte :new Date(Date.UTC (2012, 0, 2)) } }},{ $project:{ "clock":{ $let:{ vars:{ "hour":{ $substr:["$created_on", 11, -1] }, "am_pm":{ $cond:{ if:{ $lt:[ {$hour :"$created_on" }, 12 ] } , então:'AM', else:'PM'} } }, in:{ $concat :[ "$$hora", " ", "$$am_pm"] } } } }},{ $limit :10}]);dataSet.forEach(function(document) { printjson(document);}); 
Resultando em:
"clock" :"16:07:14 PM""clock" :"22:14:42 PM""clock" :"21:46:12 PM""clock" :"03:35:00 AM ""relógio" :"04:14:20 AM""relógio" :"03:41:39 AM""relógio" :"17:08:35 PM""relógio" :"18:44:02 PM"" clock" :"19:36:07 PM""clock" :"07:37:55 AM"

Conclusão

A versão 2.6 do MongoDB vem com muitas outras melhorias como operações em massa ou interseção de índice. O MongoDB está em constante evolução, oferecendo uma alternativa viável para armazenamento baseado em documentos. Com essa taxa de desenvolvimento, não é de admirar que tenha sido nomeado o banco de dados de 2013 do ano.