Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将mongodb查询的结果分组并在Java中实现?_Java_Mongodb - Fatal编程技术网

如何将mongodb查询的结果分组并在Java中实现?

如何将mongodb查询的结果分组并在Java中实现?,java,mongodb,Java,Mongodb,我在Mongo数据库中有一个集合,如下所示: { "_id" : ObjectId("561b42d4e4b0d4227d011d2c"), "product_related_data" : { "depth" : 6, "height" : 23, "product_barcode" : "54491472", "product_name" : "xyz product", "product_uui

我在Mongo数据库中有一个集合,如下所示:

{
    "_id" : ObjectId("561b42d4e4b0d4227d011d2c"),
    "product_related_data" : {
        "depth" : 6,
        "height" : 23,
        "product_barcode" : "54491472",
        "product_name" : "xyz product",
        "product_uuid" : "009b9846-b3ad-49f7-a7a0-d35a04f83480",
        "width" : 6
    },
    "sensostrip_data" : {
        "barcode" : "130150208299",
        "battery_level" : 2.894
    },
    "stock_related_data" : {
        "calculated_max_product_percentage" : 15.625,
        "calculated_min_product_percentage" : 12.5,
        "current_stock" : 2,
        "max_stock" : 6,
        "stock_difference_percentage" : 0,
        "stock_difference_value" : 0,
        "stock_percentage" : 37.5
    },
    "store_data" : {
        "city_uuid" : "cbb4dfe8-172b-11e4-a1f0-00163ed23ec2",
        "ip" : "10.0.1.1",
        "retailer_uuid" : "8c33c32c-5903-11e4-a1f0-00163ed23ec2",
        "store_name" : "xyz store",
        "store_uuid" : "15a6cc90-081f-11e5-b213-001e6745ff8d"
    },
    "time" : {
        "check_date" : "2015-10-11 11:53:55",
        "previous_check_date" : "2015-10-11 11:48:57"
    },
    "id" : "6be54bef-0aa3-456c-b912-1731f8154e7d"
}
db.readings
.find({ $and:[ {"store_data.store_uuid": {$in:["15a6cc90-081f-11e5-b213-001e6745ff8d","217b983b-5904-11e4-a1f0-00163ed23ec2","5337d78d-5904-11e4-a1f0-00163ed23ec2"]}}
,{"product_related_data.product_uuid": "f44aa29d-09ce-4902-bf12-d45d44b3dfd0"}]})
DBCollection table = databaseConncetion().getCollection("readings");

BasicDBObject sensorReturn = new BasicDBObject("sensostrip_data.barcode",1);

BasicDBObject clause1 = new BasicDBObject("store_data.store_uuid", new BasicDBObject("$in", StoreIds));

BasicDBObject clause2 = new BasicDBObject("product_related_data.product_uuid", productId);

BasicDBList and = new BasicDBList();
and.add(clause1);
and.add(clause2);

DBObject query = new BasicDBObject("$and", and);

DBCursor cursor = table.find(query, sensorReturn
        .append("stock_related_data.stock_percentage",1)
        .append("store_data.store_uuid",1)
        .append("time.check_date", 1))
        .sort(new BasicDBObject("time.check_date", -1))
        .limit(100);
我当前执行的mongo查询将返回门店ID列表和产品ID列表的所有文档,如下所示:

{
    "_id" : ObjectId("561b42d4e4b0d4227d011d2c"),
    "product_related_data" : {
        "depth" : 6,
        "height" : 23,
        "product_barcode" : "54491472",
        "product_name" : "xyz product",
        "product_uuid" : "009b9846-b3ad-49f7-a7a0-d35a04f83480",
        "width" : 6
    },
    "sensostrip_data" : {
        "barcode" : "130150208299",
        "battery_level" : 2.894
    },
    "stock_related_data" : {
        "calculated_max_product_percentage" : 15.625,
        "calculated_min_product_percentage" : 12.5,
        "current_stock" : 2,
        "max_stock" : 6,
        "stock_difference_percentage" : 0,
        "stock_difference_value" : 0,
        "stock_percentage" : 37.5
    },
    "store_data" : {
        "city_uuid" : "cbb4dfe8-172b-11e4-a1f0-00163ed23ec2",
        "ip" : "10.0.1.1",
        "retailer_uuid" : "8c33c32c-5903-11e4-a1f0-00163ed23ec2",
        "store_name" : "xyz store",
        "store_uuid" : "15a6cc90-081f-11e5-b213-001e6745ff8d"
    },
    "time" : {
        "check_date" : "2015-10-11 11:53:55",
        "previous_check_date" : "2015-10-11 11:48:57"
    },
    "id" : "6be54bef-0aa3-456c-b912-1731f8154e7d"
}
db.readings
.find({ $and:[ {"store_data.store_uuid": {$in:["15a6cc90-081f-11e5-b213-001e6745ff8d","217b983b-5904-11e4-a1f0-00163ed23ec2","5337d78d-5904-11e4-a1f0-00163ed23ec2"]}}
,{"product_related_data.product_uuid": "f44aa29d-09ce-4902-bf12-d45d44b3dfd0"}]})
DBCollection table = databaseConncetion().getCollection("readings");

BasicDBObject sensorReturn = new BasicDBObject("sensostrip_data.barcode",1);

BasicDBObject clause1 = new BasicDBObject("store_data.store_uuid", new BasicDBObject("$in", StoreIds));

BasicDBObject clause2 = new BasicDBObject("product_related_data.product_uuid", productId);

BasicDBList and = new BasicDBList();
and.add(clause1);
and.add(clause2);

DBObject query = new BasicDBObject("$and", and);

DBCursor cursor = table.find(query, sensorReturn
        .append("stock_related_data.stock_percentage",1)
        .append("store_data.store_uuid",1)
        .append("time.check_date", 1))
        .sort(new BasicDBObject("time.check_date", -1))
        .limit(100);
我当前的Java实现(我使用投影)如下所示:

{
    "_id" : ObjectId("561b42d4e4b0d4227d011d2c"),
    "product_related_data" : {
        "depth" : 6,
        "height" : 23,
        "product_barcode" : "54491472",
        "product_name" : "xyz product",
        "product_uuid" : "009b9846-b3ad-49f7-a7a0-d35a04f83480",
        "width" : 6
    },
    "sensostrip_data" : {
        "barcode" : "130150208299",
        "battery_level" : 2.894
    },
    "stock_related_data" : {
        "calculated_max_product_percentage" : 15.625,
        "calculated_min_product_percentage" : 12.5,
        "current_stock" : 2,
        "max_stock" : 6,
        "stock_difference_percentage" : 0,
        "stock_difference_value" : 0,
        "stock_percentage" : 37.5
    },
    "store_data" : {
        "city_uuid" : "cbb4dfe8-172b-11e4-a1f0-00163ed23ec2",
        "ip" : "10.0.1.1",
        "retailer_uuid" : "8c33c32c-5903-11e4-a1f0-00163ed23ec2",
        "store_name" : "xyz store",
        "store_uuid" : "15a6cc90-081f-11e5-b213-001e6745ff8d"
    },
    "time" : {
        "check_date" : "2015-10-11 11:53:55",
        "previous_check_date" : "2015-10-11 11:48:57"
    },
    "id" : "6be54bef-0aa3-456c-b912-1731f8154e7d"
}
db.readings
.find({ $and:[ {"store_data.store_uuid": {$in:["15a6cc90-081f-11e5-b213-001e6745ff8d","217b983b-5904-11e4-a1f0-00163ed23ec2","5337d78d-5904-11e4-a1f0-00163ed23ec2"]}}
,{"product_related_data.product_uuid": "f44aa29d-09ce-4902-bf12-d45d44b3dfd0"}]})
DBCollection table = databaseConncetion().getCollection("readings");

BasicDBObject sensorReturn = new BasicDBObject("sensostrip_data.barcode",1);

BasicDBObject clause1 = new BasicDBObject("store_data.store_uuid", new BasicDBObject("$in", StoreIds));

BasicDBObject clause2 = new BasicDBObject("product_related_data.product_uuid", productId);

BasicDBList and = new BasicDBList();
and.add(clause1);
and.add(clause2);

DBObject query = new BasicDBObject("$and", and);

DBCursor cursor = table.find(query, sensorReturn
        .append("stock_related_data.stock_percentage",1)
        .append("store_data.store_uuid",1)
        .append("time.check_date", 1))
        .sort(new BasicDBObject("time.check_date", -1))
        .limit(100);

但是,我需要使用此查询将最新检查日期的结果按条形码进行分组聚合框架由您自行决定。运行以下聚合管道将获得所需的结果:


蒙戈壳牌公司

pipeline = [
    {
        "$match": {
            "store_data.store_uuid": {
                "$in": [
                    "15a6cc90-081f-11e5-b213-001e6745ff8d",
                    "217b983b-5904-11e4-a1f0-00163ed23ec2",
                    "5337d78d-5904-11e4-a1f0-00163ed23ec2"
                ]
            },
            "product_related_data.product_uuid": "f44aa29d-09ce-4902-bf12-d45d44b3dfd0"
        }
    },
    { "$sort": { "time.check_date": -1 } },
    {
        "$group": {
            "_id": "$sensostrip_data.barcode",
            "stock_percentage": { "$first": "$stock_related_data.stock_percentage" },
            "store_uuid": { "$first": "$store_data.store_uuid" },
            "check_date": { "$first": "$time.check_date" }
        }
    },
    { "$limit": 100 }
];
db.readings.aggregate(pipeline);

Java测试实现

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

        MongoClient mongo = new MongoClient();
        DB db = mongo.getDB("test");

        DBCollection coll = db.getCollection("readings");

        // create the pipeline operations, first with the $match
        DBObject match = new BasicDBObject("$match",
                        new BasicDBObject("store_data.store_uuid", new BasicDBObject("$in", StoreIds))
                            .append("product_related_data.product_uuid", productId)                         
                    );

        // sort pipeline
        DBObject sort = new BasicDBObject("$sort",
                            new BasicDBObject("time.check_date", -1)
                        );

        // build the $group operations
        DBObject groupFields = new BasicDBObject( "_id", "$sensostrip_data.barcode"); // group by barcode
        groupFields.put("stock_percentage", new BasicDBObject( "$first", "$stock_related_data.stock_percentage")); // get the first when ordered documents are grouped
        groupFields.put("store_uuid", new BasicDBObject( "$first", "$store_data.store_uuid"));
        groupFields.put("check_date", new BasicDBObject( "$first", "$time.check_date"));
        // append any other necessary fields

        DBObject group = new BasicDBObject("$group", groupFields);

        // limit step
        DBObject limit = new BasicDBObject("$limit", 100);

        // put all together 
        List<DBObject> pipeline = Arrays.asList(match, sort, group, limit);

        AggregationOutput output = coll.aggregate(pipeline);

        for (DBObject result : output.results()) {
            System.out.println(result);
        }
    }
}
公共类JavaAggregation{
公共静态void main(字符串args[])引发UnknownHostException{
MongoClient mongo=新的MongoClient();
DB=mongo.getDB(“测试”);
DBCollection coll=db.getCollection(“读数”);
//创建管道操作,首先使用$match
DBObject match=新的基本对象($match),
新的BasicDBObject(“store_data.store_uuid”,新的BasicDBObject(“$in”,storeId))
.append(“与产品相关的产品数据.产品ID”,产品ID)
);
//排序管道
DBObject sort=新的BasicDBObject(“$sort”,
新的BasicDBObject(“time.check_date”,-1)
);
//构建$group操作
DBObject groupFields=new BasicDBObject(“\u id”,“$sensostrip\u data.barcode”);//按条形码分组
groupFields.put(“stock_percentage”,new basicdbobobject(“$first”,“$stock_related_data.stock_percentage”);//对订购文档进行分组时获取第一个
groupFields.put(“store_uuid”,新的BasicDBObject(“$first”,“$store_data.store_uuid”);
groupFields.put(“check_date”,新的BasicDBObject(“$first”,“$time.check_date”);
//附加任何其他必要的字段
DBObject group=新的BasicDBObject(“$group”,groupFields);
//极限步
DBObject limit=新的基本对象(“$limit”,100);
//拼凑
列表管道=数组.asList(匹配、排序、组、限制);
AggregationOutput输出=集合聚合(管道);
for(DBObject结果:output.results()){
系统输出打印项次(结果);
}
}
}

非常感谢您的详尽回答。我查询的数据集是每5分钟从传感器获得的读数,因此数据库中有数百万条记录。你在这里用过什么很贵的东西吗?我的理解是,在mongo中使用$group非常昂贵,对吗?与您的理解相反,事实并非如此,聚合管道的性能受多个因素的约束。使用聚合,计算在服务器上完成,其性能与执行
find()
查询一样,是通用聚合操作的映射/减少的更快替代方法。请参考手册,了解如何在这样的数据量下提高性能的详细说明,您希望继续阅读。