Mongodb 在聚合中对多个值进行分组
我想将集合的“所有”字段分组为“唯一总计”。假设有这样的集合:Mongodb 在聚合中对多个值进行分组,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我想将集合的“所有”字段分组为“唯一总计”。假设有这样的集合: id country state operator 121 IN HR AIRTEL 212 IN MH AIRTEL 213 US LA AT&T 214 UK JK VODAFONE 输出应如下所示: id country state operator 121 IN HR AIRTEL
id country state operator
121 IN HR AIRTEL
212 IN MH AIRTEL
213 US LA AT&T
214 UK JK VODAFONE
输出应如下所示:
id country state operator
121 IN HR AIRTEL
212 IN MH AIRTEL
213 US LA AT&T
214 UK JK VODAFONE
{
“国家”:{“在”:2,“美国”:1,“英国”:1},
“州”:{“HR”:1,“MH”:1,“LA”:1,“JK”:1},
“接线员”:{“AIRTEL”:2,“AT&T”:1,“沃达丰”:1}
}
我正在尝试使用mongo聚合框架,但无法真正思考如何做到这一点?我在下面的代码中找到了一些类似于使用聚合检查的输出
db.collectionName.aggregate({
"$group": {
"_id": null,
"countryOfIN": {
"$sum": {
"$cond": [{
$eq: ["$country", "IN"]
}, 1, 0]
}
},
"countryOfUK": {
"$sum": {
"$cond": [{
$eq: ["$country", "UK"]
}, 1, 0]
}
},
"countryOfUS": {
"$sum": {
"$cond": [{
$eq: ["$country", "US"]
}, 1, 0]
}
},
"stateOfHR": {
"$sum": {
"$cond": [{
$eq: ["$state", "HR"]
}, 1, 0]
}
},
"stateOfMH": {
"$sum": {
"$cond": [{
$eq: ["$state", "MH"]
}, 1, 0]
}
},
"stateOfLA": {
"$sum": {
"$cond": [{
$eq: ["$state", "LA"]
}, 1, 0]
}
},
"stateOfJK": {
"$sum": {
"$cond": [{
$eq: ["$state", "JK"]
}, 1, 0]
}
},
"operatorOfAIRTEL": {
"$sum": {
"$cond": [{
$eq: ["$operator", "AIRTEL"]
}, 1, 0]
}
},
"operatorOfAT&T": {
"$sum": {
"$cond": [{
$eq: ["$operator", "AT&T"]
}, 1, 0]
}
},
"operatorOfVODAFONE": {
"$sum": {
"$cond": [{
$eq: ["$operator", "VODAFONE"]
}, 1, 0]
}
}
}
}, {
"$group": {
"_id": null,
"country": {
"$push": {
"IN": "$countryOfIN",
"UK": "$countryOfUK",
"US": "$countryOfUS"
}
},
"STATE": {
"$push": {
"HR": "$stateOfHR",
"MH": "$stateOfMH",
"LA": "$stateOfLA",
"JK": "$stateOfJK"
}
},
"operator": {
"$push": {
"AIRTEL": "$operatorOfAIRTEL",
"AT&T": "$operatorOfAT&T",
"VODAFONE": "$operatorOfVODAFONE"
}
}
}
}, {
"$project": {
"_id": 0,
"country": 1,
"STATE": 1,
"operator": 1
}
})
使用已创建的匹配数据组,并将它们分为第二组进行组合。您正在寻找的输出格式并不真正适合聚合框架,因为您正在将部分数据转换为“键”名称。聚合框架不这样做,而是坚持数据库“最佳实践”,因为它不会以任何方式将“数据”转换为“键”名称 您可以使用执行mapReduce操作,以允许更灵活的操作,但由于需要使用JavaScript代码来执行操作,因此性能不佳:
db.collection.mapReduce(
函数(){
var obj={},
doc=这个;
删除单据。\u id;
Object.key(doc.forEach)函数(key){
obj[key]={};
obj[key][doc[key]]=1;
});
发射(空,obj);
},
功能(键、值){
var result={};
values.forEach(函数(值){
Object.keys(值).forEach(函数(outerKey){
Object.key(值[outerKey]).forEach(函数(innerKey){
如果(!result.hasOwnProperty(outerKey)){
结果[outerKey]={};
}
if(结果[outerKey].hasOwnProperty(innerKey)){
结果[outerKey][innerKey]+=值[outerKey][innerKey];
}否则{
结果[outerKey][innerKey]=值[outerKey][innerKey];
}
});
});
});
返回结果;
},
{“out”:{“inline”:1}
)
在适用于所有mapReduce结果的结构中:
{
“结果”:[
{
“_id”:空,
“价值”:{
“国家”:{
“IN”:2,
"美国":一,,
“英国”:1
},
“国家”:{
“人力资源”:1,
“MH”:1,
“LA”:1,
“JK”:1
},
“操作员”:{
“空中电话”:2,
“AT&T”:1,
“沃达丰”:1
}
}
}
]
}
对于聚合框架本身,它更适合生成结构更一致的聚合结果:
db.mapex.aggregate([
{“$project”:{
“国家”:1,
“国家”:1,
“操作员”:1,
“类型:{“$literal”:[“国家”、“州”、“运算符”]}
}},
{“$unwind”:“$type”},
{“$组”:{
“_id”:{
“类型”:“$type”,
“键”:{“$cond”:{
“如果”:{“$eq”:[“$type”,“country”]},
“然后”:“$country”,
“else”:{“$cond”:{
“if”:{“$eq”:[“$type”,“state”]},
“然后”:“$state”,
“else”:“$operator”
}}
}}
},
“计数”:{“$sum”:1}
}}
])
这将产生:
{u id:{“type”:“state”,“key”:“JK”},“count”:1}
{u id:{“type”:“country”,“key”:“UK”},“count”:1}
{{u id:{“type”:“country”,“key”:“US”},“count”:1}
{u id:{type:“operator”,“key:“AT&T”},“count”:1}
{u id:{“type”:“state”,“key”:“LA”},“count”:1}
{u id:{“type”:“operator”,“key”:“AIRTEL”},“count”:2}
{u id:{“type”:“state”,“key”:“MH”},“count”:1}
{u id:{type:“state”,“key:“HR”},“count”:1}
{u id:{“type”:“operator”,“key”:“VODAFONE”},“count”:1}
{u id:{“type”:“country”,“key”:“IN”},“count”:2}
但在迭代结果时,在客户机代码中进行转换相当容易:
var result={};
db.mapex.aggregate([
{“$project”:{
“国家”:1,
“国家”:1,
“操作员”:1,
“类型:{“$literal”:[“国家”、“州”、“运算符”]}
}},
{“$unwind”:“$type”},
{“$组”:{
“_id”:{
“类型”:“$type”,
“键”:{“$cond”:{
“如果”:{“$eq”:[“$type”,“country”]},
“然后”:“$country”,
“else”:{“$cond”:{
“if”:{“$eq”:[“$type”,“state”]},
“然后”:“$state”,
“else”:“$operator”
}}
}}
},
“计数”:{“$sum”:1}
}}
]).forEach(功能(文档){
如果(!result.hasOwnProperty(doc.\u id.type))
结果[doc.\u id.type]={};
结果[doc.\u id.type][doc.\u id.key]=doc.count;
})
在“结果”中给出了最终结构:
{
“国家”:{
“JK”:1,
“LA”:1,
“MH”:1,
“人力资源”:1
},
“国家”:{
“英国”:1,
"美国":一,,
“IN”:2
},
“操作员”:{
“AT&T”:1,
“空中电话”:2,
“沃达丰”:1
}
}
不可能使用聚合框架
。你需要使用Map Reduce
@BatScream你能给出一些例子或链接来参考吗?-这应该是一个非常简单和有效的起点。