Mongo聚合与展开操作

时间:2016-05-23 06:10:13

标签: mongodb aggregation-framework

我正在尝试为以下数据运行Mongo聚合:

 { 
    "name" : "xyz",
    "source" : NumberLong(1),
    "count" : NumberLong(10),
    "catIds" : [
            "dest1",
            "dest2",
            "dest3",
            "dest4"
    ]
 },
 { 
    "name" : "xyz",
    "source" : NumberLong(2),
    "count" : NumberLong(15),
    "catIds" : [
            "dest1",
            "dest2",
            "dest5",
            "dest6"
    ]
 },
 { 
    "name" : "xyz",
    "source" : NumberLong(3),
    "count" : NumberLong(1),
    "catIds" : [
            "dest1",
            "dest2",
            "dest3",
            "dest7"
    ]
 },
 { 
    "name" : "xyz",
    "source" : NumberLong(1),
    "count" : NumberLong(20),
    "catIds" : [
            "dest1",
            "dest2",
            "dest3",
            "dest4"
    ]
 },
 { 
    "name" : "xyz",
    "source" : NumberLong(2),
    "count" : NumberLong(20),
    "catIds" : [
            "dest1",
            "dest2",
            "dest3",
            "dest4"
    ]
}

输出应该是这样的

{ 
    "name" : "xyz",
    "source" : NumberLong(1),
    "count" : NumberLong(30),
    "catIds" : [
            "dest1":30,
            "dest2":30,
            "dest3":30,
            "dest4":30
    ]
},
{ 
    "name" : "xyz",
    "source" : NumberLong(2),
    "count" : NumberLong(35),
    "catIds" : [
            "dest1":35,
            "dest2":35,
            "dest3":20,
            "dest4":20,
            "dest5":15,
            "dest6":15
    ]
},
{ 
    "name" : "xyz",
    "source" : NumberLong(3),
    "count" : NumberLong(1),
    "catIds" : [
            "dest1",
            "dest2",
            "dest3",
            "dest7"
    ]
}  

我正在尝试此代码

private Map<String, Set<String>> getDailyCountForAllCat() {
        Cursor results = null;
        DBObject match = null;
        DBObject group = null;
        DBObject group2 = null;
        DBObject fields = new BasicDBObject("name", 1);
        fields.put("count", 1);
        fields.put("issource", 1);
        fields.put("catIds", 1);
        fields.put("_id", 0);
        DBObject project = new BasicDBObject("$project", fields);

        DBObject unwind = new BasicDBObject("$unwind", "$catIds");
        DB historyDb = mongoHistory.getDB("db");
        DBCollection coll = historyDb
                .getCollection("coll");

        match = new BasicDBObject("$match", new BasicDBObject("count",new BasicDBObject("$gte",1))
                .sourceend(
                        "timeStamp", BasicDBObjectBuilder.start("$gte", 1463855400l)
                        .add("$lt", 1463941800l).get()));
        System.out.println(match);

        Map<String, Object> dbObjIdMap = new HashMap<String, Object>();
        dbObjIdMap.put("name", "$name");
        dbObjIdMap.put("issource", "$issource");
        dbObjIdMap.put("catIds", "$catIds");

        DBObject groupFields = new BasicDBObject("_id", new BasicDBObject(
                dbObjIdMap));
        groupFields.put("issourceCount", new BasicDBObject("$sum", "$count"));
        group = new BasicDBObject("$group", groupFields);

        Map<String, Object> dbObjIdMap2 = new HashMap<String, Object>();
        dbObjIdMap2.put("name", "$_id.name");
        dbObjIdMap2.put("issource", "$_id.issource");
        DBObject groupFields2 = new BasicDBObject("_id", new BasicDBObject(
                dbObjIdMap2));
        groupFields2.put(
                "catIds",
                new BasicDBObject("$push", new BasicDBObject("catId",
                        "$_id.catIds").sourceend("catCount",
                        "$issourceCount")));
        groupFields2.put("count", new BasicDBObject("$sum", "$issourceCount"));

        group2 = new BasicDBObject("$group", groupFields2);

        AggregationOptions aggregationOptions = AggregationOptions.builder()
                .batchSize(1000)
                .outputMode(AggregationOptions.OutputMode.CURSOR)
                .allowDiskUse(true).build();
        results = coll.aggregate(Arrays.asList(match, project,group, unwind,group2),
                aggregationOptions);

        final Iterator<DBObject> iterator = results;

        Iterable<DBObject> iterableResults = new Iterable<DBObject>() {

            @Override
            public Iterator<DBObject> iterator() {
                return iterator;
            }
        };

        Iterator<DBObject> dbi = iterableResults.iterator();
        Map<String,List<sourceCatCount>> nameMap = new LinkedHashMap<String, List<sourceCatCount>>();
        while (dbi.hasNext()) {
            try {
                DBObject dbo = dbi.next();
                System.out.println(dbo);
                DBObject id = (DBObject) dbo.get("_id");
                String name = id.get("name").toString();

                String issource = id.get("issource").toString();
                Object obj = dbo.get("count");

                BasicDBList catList = null;
                Long countVal = 0l;
                        try {
                            countVal = ((Double) Double.parseDouble(obj.toString()))
                                    .longValue();

                        } catch (Exception e) {
                            countVal = ((Double) obj).longValue();
                        }
                try {
                    catList = (BasicDBList) (dbo.get("catIds"));
                    for(Object bdb : catList){
                        if(bdb instanceof BasicDBObject){
                            String catVal = "";
                            Long sum = 0l;
                            catVal = ((BasicDBObject) bdb).getString("catId");
                            try {
                                sum = ((Double) Double.parseDouble(((BasicDBObject) bdb).getString("catCount")))
                                        .longValue();

                            } catch (Exception e) {
                                sum = Long.parseLong(((BasicDBObject) bdb).getString("catCount"));
                            }
                            List<sourceCatCount> catListClass = null;
                            if (nameMap.containsKey(name)) {
                                catListClass = nameMap.get(name);
                            } else {
                                catListClass = new LinkedList<NewUtil.sourceCatCount>();
                            }
                            sourceCatCount sourceCatCount = new sourceCatCount(Long.parseLong(issource), catVal, countVal,sum);
                            catListClass.add(sourceCatCount);
                            nameMap.put(name, catListClass);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }


            } catch (Exception e1) {

            }
        }

        Long total = 0l;
        for(String key : nameMap.keySet()){
            List<sourceCatCount> catList = nameMap.get(key);
            System.out.println(key+"---------------"+catList.size());
            for(sourceCatCount cl : catList){
                total = total + cl.getCount();
            }
            System.out.println(key+"-----------"+total);
            total = 0l;
        }

        return null;
    }

    class sourceCatCount{
        Long issource;
        String catId;
        Long count;
        Long catCount;

        public sourceCatCount(Long issource,String catId,Long count,Long catCount) {
            this.issource = issource;
            this.catId = catId;
            this.count = count;
            this.catCount = catCount;
        }

        public Long getIssource() {
            return issource;
        }

        public void setIssource(Long issource) {
            this.issource = issource;
        }

        public String getCatId() {
            return catId;
        }

        public void setCatId(String catId) {
            this.catId = catId;
        }

        public Long getCount() {
            return count;
        }

        public void setCount(Long count) {
            this.count = count;
        }

        public Long getCatCount() {
            return catCount;
        }

        public void setCatCount(Long catCount) {
            this.catCount = catCount;
        }


    } 

上面给出了结果,其中count字段是数组字段中所有计数的总和但不应该是这种情况。你能帮我写一个带有展开操作的聚合方法来达到预期的效果吗?

0 个答案:

没有答案