jar*_*ery 5 mongodb mongodb-query aggregation-framework
我的收藏看起来像这样.
{
"_id" : ObjectId("572c4ed33c1b5f51215219a8"),
"name" : "This is an angular course, and integeration with php",
"description" : "After we connected we can query or update the database just how we would using the mongo API with the exception that we use a callback. The format for callbacks is always callback(error, value) where error is null if no exception has occured. The update methods save, remove, update and findAndModify also pass the lastErrorObject as the last argument to the callback function.",
"difficulty_level" : "Beginner",
"type" : "Fast Track",
"tagged_skills" : [
{
"_id" : "5714e894e09a0f7d804b2254",
"name" : "PHP"
},
{
"_id" : "5717355806313b1f1715fa50",
"name" : "c++"
},
{
"_id" : "5715025bc2c5dbb4675180da",
"name" : "java"
},
{
"_id" : "5714f188ec325f5359979e33",
"name" : "symphony"
}
]}
Run Code Online (Sandbox Code Playgroud)
我希望根据类型,难度级别和标记技能对集合进行分组,并在单个查询中获取计数.
我无法增加技能数量.
我的查询如下: -
db.course.aggregate([
{$unwind:"$tagged_skills"},
{$group:{
_id:null,
skills: { $addToSet: "$tagged_skills.name" },
Normal_df:{$sum:{
"$cond": [
{ "$eq":[ "$difficulty_level","Normal"] },
1,
0
]
}},
Beginner_df:{$sum:{
"$cond": [
{ "$eq":[ "$difficulty_level","Beginner"] },
1,
0
]
}},
Intermediate_df:{$sum:{
"$cond": [
{ "$eq":[ "$difficulty_level","Intermediate"] },
1,
0
]
}},
Advanced_df:{$sum:{
"$cond": [
{ "$eq":[ "$difficulty_level","Advanced"] },
1,
0
]
}},
Fast_Track_type:{$sum:{
"$cond": [
{ "$eq":[ "$type","Fast Track"] },
1,
0
]
}},
Normal_type:{$sum:{
"$cond": [
{ "$eq":[ "$type","Normal"] },
1,
0
]
}},
Beginner_type:{$sum:{
"$cond": [
{ "$eq":[ "$type","Beginner"] },
1,
0
]
}},
Normal_Track_type:{$sum:{
"$cond": [
{ "$eq":[ "$type","Normal Track"] },
1,
0
]
}},
}}
])
Run Code Online (Sandbox Code Playgroud)
结果如下: -
{
"_id" : null,
"skills" : [
"SQL",
"PHP",
"java",
"Angular Js",
"Laravel 23",
"c++",
"Node Js",
"symphony",
"Mysql",
"Express Js",
"JAVA"
],
"Normal_df" : 1,
"Beginner_df" : 14,
"Intermediate_df" : 7,
"Advanced_df" : 2,
"Fast_Track_type" : 8,
"Normal_type" : 6,
"Beginner_type" : 1,
"Normal_Track_type" : 9
}
Run Code Online (Sandbox Code Playgroud)
我也希望获得所有技能.
要获得所有技能的数量,您需要首先获得所有技能的列表。distinct您可以通过在适当的字段上运行命令来获取此列表。通过此列表,您可以构建$group将使用$sum和$cond运算符的适当管道文档。
考虑以下用例:
var difficultyLevels = db.course.distinct("difficulty_level"),
types = db.course.distinct("type"),
skills = db.course.distinct("tagged_skills.name"),
unwindOperator = { "$unwind": "$tagged_skills" },
groupOperator = {
"$group": {
"_id": null,
"skills": { "$addToSet": "$tagged_skills.name" }
}
};
difficultyLevels.forEach(function (df){
groupOperator["$group"][df+"_df"] = {
"$sum": {
"$cond": [ { "$eq": ["$difficulty_level", df] }, 1, 0]
}
}
});
types.forEach(function (type){
groupOperator["$group"][type.replace(" ", "_")+"_type"] = {
"$sum": {
"$cond": [ { "$eq": ["$type", type] }, 1, 0]
}
}
});
skills.forEach(function (skill){
groupOperator["$group"][skill] = {
"$sum": {
"$cond": [ { "$eq": ["$tagged_skills.name", skill] }, 1, 0]
}
}
});
//printjson(groupOperator);
db.course.aggregate([unwindOperator, groupOperator]);
Run Code Online (Sandbox Code Playgroud)
在第一行中,我们通过在字段distinct上运行命令来获取包含难度级别的数组difficulty_level
db.course.distinct("difficulty_level")
Run Code Online (Sandbox Code Playgroud)
这将产生数组
var difficultyLevels = ["Normal", "Beginner", "Intermediate", "Advanced"]
Run Code Online (Sandbox Code Playgroud)
同样,前面的distinct操作将返回该键的可能唯一值的列表。
获取这些列表后,您可以使用该方法创建管道对象forEach()来填充列表中每个给定项目的文档键。然后您可以使用生成的文档,如下所示
printjson(groupOperator);
{
"$group" : {
"_id" : null,
"skills" : {
"$addToSet" : "$tagged_skills.name"
},
"Beginner_df" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$difficulty_level",
"Beginner"
]
},
1,
0
]
}
},
"Intermediate_df" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$difficulty_level",
"Intermediate"
]
},
1,
0
]
}
},
"Fast_Track_type" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$type",
"Fast Track"
]
},
1,
0
]
}
},
"PHP" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$tagged_skills.name",
"PHP"
]
},
1,
0
]
}
},
"c++" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$tagged_skills.name",
"c++"
]
},
1,
0
]
}
},
"java" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$tagged_skills.name",
"java"
]
},
1,
0
]
}
},
"symphony" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$tagged_skills.name",
"symphony"
]
},
1,
0
]
}
},
"C#" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$tagged_skills.name",
"C#"
]
},
1,
0
]
}
},
"Scala" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$tagged_skills.name",
"Scala"
]
},
1,
0
]
}
},
"javascript" : {
"$sum" : {
"$cond" : [
{
"$eq" : [
"$tagged_skills.name",
"javascript"
]
},
1,
0
]
}
}
}
}
Run Code Online (Sandbox Code Playgroud)