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

Agregar $group para vários períodos


Você precisa determinar condicionalmente a chave de agrupamento com base em onde a data atual está entre o intervalo. Isso é basicamente obtido por meio de $cond com condições aninhadas e a variante lógica de $lt :
// work out dates somehow
var today = new Date(),
    oneDay = ( 1000 * 60 * 60 * 24 ),
    thirtyDays = new Date( today.valueOf() - ( 30 * oneDay ) ),
    fifteenDays = new Date( today.valueOf() - ( 15 * oneDay ) ),
    sevenDays = new Date( today.valueOf() - ( 7 * oneDay ) );

db.collection.aggregate([
    { "$match": {
        "date": { "$gte": thirtyDays }
    }},
    { "$group": {
        "_id": {
            "$cond": [
                { "$lt": [ "$date", fifteenDays ] },
                "16-30",
                { "$cond": [
                    { "$lt": [ "$date", sevenDays ] },
                    "08-15",
                    "01-07"
                ]}
            ]
        },
        "count": { "$sum": 1 },
        "totalValue": { "$sum": "$value" }
    }}
])

Como $cond é um operador ternário, a primeira condição é avaliada para ver se a condição é verdadeira e, quando verdadeira, o segundo argumento é retornado, caso contrário, o terceiro é retornado quando falso. Então, aninhando outro $cond no caso falso, você obtém o teste lógico de onde a data cai, "menos que a data de 15 dias", o que significa que está no intervalo mais antigo, ou "menos de 7 dias", o que significa o intervalo intermediário, ou é claro que está no intervalo a mais nova gama.

Estou apenas prefixando os números aqui menores que 10 com um 0 então dá a você algo para classificar, se quiser, já que a saída de "chaves" em $group não é em si ordenada.

Mas é assim que você faz isso em uma única consulta. Você apenas descobre qual deve ser a chave de agrupamento com base em onde a data cai e acumula para cada chave.