MongoDB - 连接两个查询结果和 dense_rank
MongoDB - joining two results of queries and dense_rank
我正在学习 MongoDB,但我在理解其概念方面遇到了一些问题。
我有一个看起来像这样的集合:
db.email.findOne()
{
"_id" : ObjectId("52af48b5d55148fa0c199646"),
"sender" : "tori.wells@enron.com",
"recipients" : [
"michael@optsevents.com"
],
"cc" : [ ],
"text" : "Mr. Christman:\n\nThank you for your invitation for Dr. Lay to speak at your upcoming forum in \nFrance, the format looks wonderful. Unfortunately, Dr. Lay has calendar \nconflicts and will be unable to participate.\n\nIf you should need further assistance, please do not hesitate to contact us.\n\nTori Wells\nExecutive Assistant",
"mid" : "22263156.1075840285610.JavaMail.evans@thyme",
"fpath" : "enron_mail_20110402/maildir/lay-k/_sent/101.",
"bcc" : [ ],
"to" : [
"michael@optsevents.com"
],
"replyto" : null,
"ctype" : "text/plain; charset=us-ascii",
"fname" : "101.",
"date" : "2000-08-04 09:04:00-07:00",
"folder" : "_sent",
"subject" : "Wall Street Journal Millennium Forum"
}
这是安然数据库。
我正在尝试进行查询,该查询将 return 列出电子邮件及其发送的邮件数量和收到的邮件数量。
我设法提出了两个看起来像这样的查询:
db.email.aggregate({$group:{_id:"$sender",SendsAmount:{$sum:1}}},{$sort:{SendsAmount:-1}})
{ "_id" : "rosalee.fleming@enron.com", "SendsAmount" : 849 }
{ "_id" : "brown_mary_jo@lilly.com", "SendsAmount" : 82 }
{ "_id" : "leonardo.pacheco@enron.com", "SendsAmount" : 78 }
db.email.aggregate({$group:{_id:"$recipients",ReceivedAmount:{$sum:1}}},{$unwind:"$_id"},{$sort:{ReceivedAmount:-1}})
{ "_id" : "klay@enron.com", "ReceivedAmount" : 1350 }
{ "_id" : "kenneth.lay@enron.com", "ReceivedAmount" : 912 }
{ "_id" : "kenneth.lay@enron.com", "ReceivedAmount" : 78 }
如您所见,第一个 return 是我的电子邮件和从它发送的电子邮件数量,第二个也是 return 的电子邮件和它收到的电子邮件数量。
我的观点是将这两者合并(?)并得到一个查询,该查询将 return 类似于:
{ "_id" : "email@enron.com", "SendsAmount" : 57, "ReceivedAmount": 43 }
我知道有 $lookup 但它只能用于两个集合,所以我的想法是从这两个查询中创建两个集合,但我觉得有更好的方法来解决我的问题。
---我的第二个问题是尝试做一些 DENSE_RANK 中不存在的 MongoDB。我想按发送的电子邮件数量对电子邮件地址进行排名。
我使用了 $unwind 和 insertArrayIndex 但我得到了类似 ROW_NUMBER 的东西,这不是我要找的。
我写过类似的东西:
db.email.aggregate({$group:{"_id":"$sender",SendsAmount:{$sum:1},rank:0}},{$sort:{"ile":-1}}).forEach(function(x){
var howmany=0;
var query=db.email.aggregate({$group:{"_id":"$sender",SendsAmount:{$sum:1}}},{$match:{ile:{$gt:x.SendsAmount}}},{$group:{_id:null, HowManyGreater:{$sum:1}}});
query.forEach(function(y){
howmany=y.HowManyGreater;
});
howmany=howmany+1;
print("email: "+ x._id + " SendsAmount: " + x.SendsAmount + " rank " + howmany+1);
});
这是给了我想要的结果,但它甚至不是文档,只是打印的信息。我读过有关 MapReduce 的资料,但我不知道在这种情况下如何使用它。
如果要在聚合查询中进行所有计算,可以使用如下的$facet和$group阶段
db.email.aggregate([
{
$facet: {
send: [
{
$group: {
_id: "$sender",
SendsAmount: {
$sum: 1
}
}
},
{
$sort: {
SendsAmount: -1
}
}
],
recieve: [
{
$group: {
_id: "$recipients",
ReceivedAmount: {
$sum: 1
}
}
},
{
$unwind: "$_id"
},
{
$sort: {
ReceivedAmount: -1
}
}
]
}
},
{
$project: {
all: {
$concatArrays: [
"$recieve",
"$send"
]
}
}
},
{
$unwind: "$all"
},
{
$group: {
_id: "$all._id",
ReceivedAmount: {
$sum: {
$cond: {
if: {
$gt: [
"$all.ReceivedAmount",
null
]
},
then: "$all.ReceivedAmount",
else: 0
}
}
},
SendsAmount: {
$sum: {
$cond: {
if: {
$gt: [
"$all.SendsAmount",
null
]
},
then: "$all.SendsAmount",
else: 0
}
}
}
}
}
])
我正在学习 MongoDB,但我在理解其概念方面遇到了一些问题。
我有一个看起来像这样的集合:
db.email.findOne()
{
"_id" : ObjectId("52af48b5d55148fa0c199646"),
"sender" : "tori.wells@enron.com",
"recipients" : [
"michael@optsevents.com"
],
"cc" : [ ],
"text" : "Mr. Christman:\n\nThank you for your invitation for Dr. Lay to speak at your upcoming forum in \nFrance, the format looks wonderful. Unfortunately, Dr. Lay has calendar \nconflicts and will be unable to participate.\n\nIf you should need further assistance, please do not hesitate to contact us.\n\nTori Wells\nExecutive Assistant",
"mid" : "22263156.1075840285610.JavaMail.evans@thyme",
"fpath" : "enron_mail_20110402/maildir/lay-k/_sent/101.",
"bcc" : [ ],
"to" : [
"michael@optsevents.com"
],
"replyto" : null,
"ctype" : "text/plain; charset=us-ascii",
"fname" : "101.",
"date" : "2000-08-04 09:04:00-07:00",
"folder" : "_sent",
"subject" : "Wall Street Journal Millennium Forum"
}
这是安然数据库。
我正在尝试进行查询,该查询将 return 列出电子邮件及其发送的邮件数量和收到的邮件数量。
我设法提出了两个看起来像这样的查询:
db.email.aggregate({$group:{_id:"$sender",SendsAmount:{$sum:1}}},{$sort:{SendsAmount:-1}})
{ "_id" : "rosalee.fleming@enron.com", "SendsAmount" : 849 }
{ "_id" : "brown_mary_jo@lilly.com", "SendsAmount" : 82 }
{ "_id" : "leonardo.pacheco@enron.com", "SendsAmount" : 78 }
db.email.aggregate({$group:{_id:"$recipients",ReceivedAmount:{$sum:1}}},{$unwind:"$_id"},{$sort:{ReceivedAmount:-1}})
{ "_id" : "klay@enron.com", "ReceivedAmount" : 1350 }
{ "_id" : "kenneth.lay@enron.com", "ReceivedAmount" : 912 }
{ "_id" : "kenneth.lay@enron.com", "ReceivedAmount" : 78 }
如您所见,第一个 return 是我的电子邮件和从它发送的电子邮件数量,第二个也是 return 的电子邮件和它收到的电子邮件数量。
我的观点是将这两者合并(?)并得到一个查询,该查询将 return 类似于:
{ "_id" : "email@enron.com", "SendsAmount" : 57, "ReceivedAmount": 43 }
我知道有 $lookup 但它只能用于两个集合,所以我的想法是从这两个查询中创建两个集合,但我觉得有更好的方法来解决我的问题。
---我的第二个问题是尝试做一些 DENSE_RANK 中不存在的 MongoDB。我想按发送的电子邮件数量对电子邮件地址进行排名。
我使用了 $unwind 和 insertArrayIndex 但我得到了类似 ROW_NUMBER 的东西,这不是我要找的。
我写过类似的东西:
db.email.aggregate({$group:{"_id":"$sender",SendsAmount:{$sum:1},rank:0}},{$sort:{"ile":-1}}).forEach(function(x){
var howmany=0;
var query=db.email.aggregate({$group:{"_id":"$sender",SendsAmount:{$sum:1}}},{$match:{ile:{$gt:x.SendsAmount}}},{$group:{_id:null, HowManyGreater:{$sum:1}}});
query.forEach(function(y){
howmany=y.HowManyGreater;
});
howmany=howmany+1;
print("email: "+ x._id + " SendsAmount: " + x.SendsAmount + " rank " + howmany+1);
});
这是给了我想要的结果,但它甚至不是文档,只是打印的信息。我读过有关 MapReduce 的资料,但我不知道在这种情况下如何使用它。
如果要在聚合查询中进行所有计算,可以使用如下的$facet和$group阶段
db.email.aggregate([
{
$facet: {
send: [
{
$group: {
_id: "$sender",
SendsAmount: {
$sum: 1
}
}
},
{
$sort: {
SendsAmount: -1
}
}
],
recieve: [
{
$group: {
_id: "$recipients",
ReceivedAmount: {
$sum: 1
}
}
},
{
$unwind: "$_id"
},
{
$sort: {
ReceivedAmount: -1
}
}
]
}
},
{
$project: {
all: {
$concatArrays: [
"$recieve",
"$send"
]
}
}
},
{
$unwind: "$all"
},
{
$group: {
_id: "$all._id",
ReceivedAmount: {
$sum: {
$cond: {
if: {
$gt: [
"$all.ReceivedAmount",
null
]
},
then: "$all.ReceivedAmount",
else: 0
}
}
},
SendsAmount: {
$sum: {
$cond: {
if: {
$gt: [
"$all.SendsAmount",
null
]
},
then: "$all.SendsAmount",
else: 0
}
}
}
}
}
])