Mongo DB + java按选定日期范围分组文件

时间:2016-10-01 06:24:51

标签: java mongodb-query aggregation-framework mongodb-aggregation

我是MongoDB的新手,使用mongoJavaDriver.jar在Java中使用它。

我的收藏中有更多文件,下面是抽样的一部分。

{
    "_id" : ObjectId("57ee4767d782023f80bd4f97"),
    "USER_NAME" : "abc123xgvdfbvdf@einrot.com",
    "LOGIN" : ISODate("2016-09-29T18:30:00Z"),
    "LOGOUT" : ISODate("2016-09-30T11:07:19.598Z"),
    "LONGITUDE" : "long",
    "LATITUDE" : "lat",
    "SOURCE" : "Web",
    "LAST_UPDATED" : ISODate("2016-09-30T11:07:19.598Z")
}
{
    "_id" : ObjectId("57ee4767d782023f80bd4f98"),
    "USER_NAME" : "abc123xgvdfbvdf@fleckens.hu",
    "LOGIN" : ISODate("2016-09-29T18:30:00Z"),
    "LOGOUT" : ISODate("2016-09-30T11:07:19.601Z"),
    "LONGITUDE" : "long",
    "LATITUDE" : "lat",
    "SOURCE" : "Web",
    "LAST_UPDATED" : ISODate("2016-09-30T11:07:19.601Z")
}
{
    "_id" : ObjectId("57ee4767d782023f80bd4f99"),
    "USER_NAME" : "prashanthtfxgvdfbvdf@gmail.com",
    "LOGIN" : ISODate("2016-09-29T18:30:00Z"),
    "LOGOUT" : ISODate("2016-09-30T11:07:19.603Z"),
    "LONGITUDE" : "long",
    "LATITUDE" : "lat",
    "SOURCE" : "Web",
    "LAST_UPDATED" : ISODate("2016-09-30T11:07:19.603Z")
}
{
    "_id" : ObjectId("57ee4767d782023f80bd4f9e"),
    "USER_NAME" : "57ee4767d782023f80bd4f9f@jourrapide.com",
    "LOGIN" : ISODate("2016-09-29T18:30:00Z"),
    "LOGOUT" : ISODate("2016-09-30T11:07:19.608Z"),
    "LONGITUDE" : "long",
    "LATITUDE" : "lat",
    "SOURCE" : "Web",
    "LAST_UPDATED" : ISODate("2016-09-30T11:07:19.608Z")
}
{
    "_id" : ObjectId("57ee4767d782023f80bd4f9f"),
    "USER_NAME" : "zxcxgvdfbvdf@jourrapide.com",
    "LOGIN" : ISODate("2016-09-29T18:30:00Z"),
    "LOGOUT" : ISODate("2016-09-30T11:07:19.609Z"),
    "LONGITUDE" : "long",
    "LATITUDE" : "lat",
    "SOURCE" : "Web",
    "LAST_UPDATED" : ISODate("2016-09-30T11:07:19.609Z")
}

我可以运行查询来查找所选日期范围内的文档,并返回一些值。

我的代码:

    Date current = new Date();
    Date current2  = new Date(current .getYear(), current.getMonth(), current.getDate()-days);
    current2.setHours(0);
    current2.setMinutes(0);
    BasicDBObject dateRange = new BasicDBObject ("$gte",current2 );
    dateRange.put("$lt", new Date(current.getYear(), current.getMonth(), current.getDate()+1));
    BasicDBObject query = new BasicDBObject("LAST_UPDATED", dateRange);
    System.out.println(collection.find().count());
    System.out.println(collection.find(query).count());

此系列中的总文件数为155.

根据所选日期计算是37。

在这些选定的37个文档中,用户名中有多余的值。我想根据USER_NAME字段对它们进行分组。所以这个数量会少于37个。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

您可以使用聚合框架来执行所需的聚合。考虑在mongo shell中运行以下聚合框架管道 它基本上使用 $match 过滤器来限制文档进入管道以便根据提供的日期范围查询进行处理,然后 使用 $group USER_NAME字段对文档进行分组,并使用 $sum 计算不同的值:

var now = new Date(),
    days = 4,
    start = new Date(now.getYear(), now.getMonth(), now.getDate()-days),
    end = new Date(now.getYear(), now.getMonth(), now.getDate()+1);
end.setHours(0);
end.setMinutes(0);
var pipeline = [
    { "$match": { "LAST_UPDATED": { "$gte": start, "$lte": end } } },
    {
        "$group": {
            "_id": "$USER_NAME",
            "count": { "$sum": 1 }
        }
    }
];
db.collection.aggregate(pipeline);

将上述内容转换为Java成为:

public class JavaAggregation {
    public static void main(String args[]) throws UnknownHostException {

        MongoClient mongo = new MongoClient();
        DB db = mongo.getDB("test"); // your database name

        DBCollection coll = db.getCollection("collectionName"); // your collection name

        // create the pipeline operations, first with the $match
        Date now = new Date();
        Date start = new Date(now.getYear(), now.getMonth(), now.getDate()-days);
        Date end  = new Date(now.getYear(), now.getMonth(), now.getDate()+1);
        end.setHours(0);
        end.setMinutes(0);
        DBObject match = new BasicDBObject("$match",
                            new BasicDBObject("LAST_UPDATED",
                                new BasicDBObject("$gte", start).append("$lt", end)
                            )
                        );

        // build the $group operations
        DBObject groupFields = new BasicDBObject( "_id", "$USER_NAME");
        groupFields.put("count", new BasicDBObject( "$sum", 1));

        DBObject group = new BasicDBObject("$group", groupFields);
        List<DBObject> pipeline = Arrays.asList(match, group);

        AggregationOutput output = coll.aggregate(pipeline);

        for (DBObject result : output.results()) {
            System.out.println(result);
        }
    }
}