我在mongo集合中有以下json结构 -
{
"students":[
{
"name":"ABC",
"fee":1233
},
{
"name":"PQR",
"fee":345
}
],
"studentDept":[
{
"name":"ABC",
"dept":"A"
},
{
"name":"XYZ",
"dept":"X"
}
]
},
{
"students":[
{
"name":"XYZ",
"fee":133
},
{
"name":"LMN",
"fee":56
}
],
"studentDept":[
{
"name":"XYZ",
"dept":"X"
},
{
"name":"LMN",
"dept":"Y"
},
{
"name":"ABC",
"dept":"P"
}
]
}
现在我想计算以下输出。 如果students.name = studentDept.name 所以我的结果应该如下
{
"name":"ABC",
"fee":1233,
"dept":"A",
},
{
"name":"XYZ",
"fee":133,
"dept":"X"
}
{
"name":"LMN",
"fee":56,
"dept":"Y"
}
我是否需要使用mongo聚合,或者是否可以在不使用聚合的情况下获得高于给定的输出???
答案 0 :(得分:0)
你在这里真正要问的是如何使MongoDB返回的东西实际上与你在集合中存储它的形式完全不同。标准查询操作允许"projection"的“限制”形式,但即使在该链接中共享的页面上的标题表明,这实际上只是“限制”字段在结果中显示基于什么是已存在于您的文档中。
因此,任何形式的“更改”都需要某种形式的聚合,聚合和mapReduce操作都允许将文档结果“重新塑造”为与输入不同的形式。也许人们特别想念聚合框架的主要问题是,它不仅仅是所有关于“聚合”,实际上“重塑”概念是其实施的核心。 / p>
所以为了得到你想要的结果,你可以采取这样的方法,这应该适用于大多数情况:
db.collection.aggregate([
{ "$unwind": "$students" },
{ "$unwind": "$studentDept" },
{ "$group": {
"_id": "$students.name",
"tfee": { "$first": "$students.fee" },
"tdept": {
"$min": {
"$cond": [
{ "$eq": [
"$students.name",
"$studentDept.name"
]},
"$studentDept.dept",
false
]
}
}
}},
{ "$match": { "tdept": { "$ne": false } } },
{ "$sort": { "_id": 1 } },
{ "$project": {
"_id": 0,
"name": "$_id",
"fee": "$tfee",
"dept": "$tdept"
}}
])
或者只是“过滤掉”两个“名称”字段不匹配的情况,然后只是将内容与您想要的字段一起投影,如果文档之间的内容交叉并不重要:
db.collection.aggregate([
{ "$unwind": "$students" },
{ "$unwind": "$studentDept" },
{ "$project": {
"_id": 0,
"name": "$students.name",
"fee": "$students.fee",
"dept": "$studentDept.dept",
"same": { "$eq": [ "$students.name", "$studentDept.name" ] }
}},
{ "$match": { "same": true } },
{ "$project": {
"name": 1,
"fee": 1,
"dept": 1
}}
])
从MongoDB 2.6及更高版本开始,您甚至可以对两个数组之间的文档执行“内联”操作。您仍然希望在最终输出中重塑该数组内容,但可能会更快一点:
db.collection.aggregate([
// Compares entries in each array within the document
{ "$project": {
"students": {
"$map": {
"input": "$students",
"as": "stu",
"in": {
"$setDifference": [
{ "$map": {
"input": "$studentDept",
"as": "dept",
"in": {
"$cond": [
{ "$eq": [ "$$stu.name", "$$dept.name" ] },
{
"name": "$$stu.name",
"fee": "$$stu.fee",
"dept": "$$dept.dept"
},
false
]
}
}},
[false]
]
}
}
}
}},
// Students is now an array of arrays. So unwind it twice
{ "$unwind": "$students" },
{ "$unwind": "$students" },
// Rename the fields and exclude
{ "$project": {
"_id": 0,
"name": "$students.name",
"fee": "$students.fee",
"dept": "$students.dept"
}},
])
因此,您希望基本上“改变”输出结构,然后您需要使用其中一个聚合工具来完成。你可以,即使你没有真正聚合任何东西。