我正在尝试为以下数据运行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字段是数组字段中所有计数的总和但不应该是这种情况。你能帮我写一个带有展开操作的聚合方法来达到预期的效果吗?