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

Map Reduzir o tipo de consulta com necessidade de correlacionar com a linha anterior


Se você estivesse fazendo isso no banco de dados relacional, não estaria comparando as visitas linha por linha, em vez disso, usaria uma consulta de agregação para encontrar visitas repetidas (usando SELECT ... GROUP BY), portanto, faça da mesma maneira no MongoDB.

Primeiro você precisa agregar visitas por cliente por loja por dia:
group1 = { "$group" : {
        "_id" : {
            "c" : "$clientId",
            "l" : "$location",
            "day" : {
                "y" : {
                    "$year" : "$tov"
                },
                "m" : {
                    "$month" : "$tov"
                },
                "d" : {
                    "$dayOfMonth" : "$tov"
                }
            }
        },
        "visits" : {
            "$sum" : 1
        }
    }
};

EDITAR como você quer apenas repetir DAYS em seguida, você agruparia por cliente, por loja e contaria quantos DIAS diferentes houve para visitas desse cliente a essa loja:
group2 = {"$group" : 
    {"_id" : {
        "c" : "$_id.c",
        "s" : "$_id.l"
    },
    "totalDays" : {
        "$sum" : 1
    }
} };

Em seguida, você deseja incluir apenas os registros acima em que houve mais de uma visita do mesmo cliente à mesma loja em vários dias:
match = { "$match" : { "totalDays" : { "$gt" : 1 } } };

Veja um exemplo de conjunto de dados e o resultado dessas agregações usando as operações de pipeline acima:
> db.visits.find({},{_id:0,purchases:0}).sort({location:1, clientId:1, tov:1})
{ "clientId" : 1, "location" : "l1", "tov" : ISODate("2013-01-01T20:00:00Z") }
{ "clientId" : 1, "location" : "l1", "tov" : ISODate("2013-01-01T21:00:00Z") }
{ "clientId" : 1, "location" : "l1", "tov" : ISODate("2013-01-03T20:00:00Z") }
{ "clientId" : 2, "location" : "l1", "tov" : ISODate("2013-01-01T21:00:00Z") }
{ "clientId" : 3, "location" : "l1", "tov" : ISODate("2013-01-01T21:00:00Z") }
{ "clientId" : 3, "location" : "l1", "tov" : ISODate("2013-01-02T21:00:00Z") }
{ "clientId" : 1, "location" : "l2", "tov" : ISODate("2013-01-01T23:00:00Z") }
{ "clientId" : 3, "location" : "l2", "tov" : ISODate("2013-01-02T21:00:00Z") }
{ "clientId" : 3, "location" : "l2", "tov" : ISODate("2013-01-02T21:00:00Z") }
{ "clientId" : 1, "location" : "l3", "tov" : ISODate("2013-01-03T20:00:00Z") }
{ "clientId" : 2, "location" : "l3", "tov" : ISODate("2013-01-04T20:00:00Z") }
{ "clientId" : 4, "location" : "l3", "tov" : ISODate("2013-01-04T20:00:00Z") }
{ "clientId" : 4, "location" : "l3", "tov" : ISODate("2013-01-04T21:00:00Z") }
{ "clientId" : 4, "location" : "l3", "tov" : ISODate("2013-01-04T22:00:00Z") }

> db.visits.aggregate(group1, group2, match)
{
    "result" : [
    {
        "_id" : {
            "c" : 3,
            "s" : "l1"
        },
        "totalDays" : 2
    },
    {
        "_id" : {
            "c" : 1,
            "s" : "l1"
        },
        "totalDays" : 2
    }
    ],
    "ok" : 1
}