Mongodb 按不同计数排序的Mongo查询

Mongodb 按不同计数排序的Mongo查询,mongodb,subquery,mongodb-query,aggregation-framework,Mongodb,Subquery,Mongodb Query,Aggregation Framework,我有两个字段“公司”和“url”。我想按不同的“公司”出现的次数对其进行排序,然后显示对应于该特定公司的三个“url”。数据存储方式如下: { "_id" : ObjectId("56c4f73664af6f7305f3670f"), "title" : "Full Stack Software Developer", "url" : "http://www.indeed.com/cmp/Upside-Commerce,-Inc./jobs/Full-Stack-Soft

我有两个字段“公司”和“url”。我想按不同的“公司”出现的次数对其进行排序,然后显示对应于该特定公司的三个“url”。数据存储方式如下:

{
    "_id" : ObjectId("56c4f73664af6f7305f3670f"),
    "title" : "Full Stack Software Developer",
    "url" : "http://www.indeed.com/cmp/Upside-Commerce,-Inc./jobs/Full-Stack-Software-Developer-6e93e36ea5d0e57e?sjdu=QwrRXKrqZ3CNX5W-O9jEvRQls7y2xdBHzhqWkvhd5FFfs8wS9wesfMWXjNNFaUXen2pO-kyc_Qbr7-_3Gf40AvyEQT3jn6IRxIwvw9-aFy8",
    "company" : "Upside Commerce, Inc."
}
下面的查询统计不同公司的数量

db.Books.aggregate({$group : { _id : '$company', count : {$sum : 1}}})
输出结果如下:

{ "_id" : "Microsoft", "count" : 14 }
{ "_id" : "Tableau", "count" : 64 }
{ "_id" : "Amazon", "count" : 64 }
{ "_id" : "Dropbox", "count" : 64 }
{ "_id" : "Amazon Corporate LLC", "count" : 64 }
{ "_id" : "Electronic Arts", "count" : 64 }
{ "_id" : "CDK Global", "count" : 65 }
{ "_id" : "IDC Technologies", "count" : 64 }
{ "_id" : "Concur", "count" : 64 }
{ "_id" : "Microsoft", "count" : 14 }
{ "_id" : "Tableau", "count" : 64 }
{ "_id" : "Amazon", "count" : 64 }
{ "_id" : "Dropbox", "count" : 64 }
{ "_id" : "Amazon Corporate LLC", "count" : 64 }
{ "_id" : "Electronic Arts", "count" : 64 }
{ "_id" : "CDK Global", "count" : 65 }
{ "_id" : "IDC Technologies", "count" : 64 }
{ "_id" : "Concur", "count" : 64 }
然而,我希望它按不同公司的数量排序(将其限制在前10名出现最多的公司),然后显示三个对应于不同公司的URL(如果不同公司的数量至少为三个)。比如:

{for microsoft:
    {"url" : "https://careers.microsoft.com/jobdetails.aspx?jid=216571&memid=1071484607&utm_source=Indeed"}
    {"url" : "https://careers.microsoft.com/jobdetails.aspx?jid=216571&memid=1695844082&utm_source=Indeed" }
    { "url" : "https://careers.microsoft.com/jobdetails.aspx?jid=216571&memid=932148152&utm_source=Indeed"}}
其他公司也一样

这确实(仍然)最好通过多个查询来处理,因为MongoDB确实“仍然”没有真正高效的运营商来完成这项工作

不过,您可以在MongoDB 3.2中执行类似的操作,但存在明显的“陷阱”:

db.Books.aggregate([
{“$组”:{
“_id”:“$company”,
“计数”:{“$sum”:1},
“URL”:{
“$push”:“$url”
}
}},
{“$sort”:{“count”:-1},
{“$limit”:10},
{“$project”:{
“计数”:1,
“URL”:{“$slice”:[“$URL”,0,3]}
}}
])
明显的问题是,不管怎样,您仍然在将“url”内容的全部添加到分组数组中。这有可能超过16MB的BSON限制。可能不会,但当您只需要“三个”内容时,添加“所有”内容仍然有点浪费

因此,即使如此,在前10个结果中,单独查询“URL”可能更为实际

下面是node.js的列表,演示了:

var async=require('async'),
mongodb=require('mongodb'),
MongoClient=mongodb.MongoClient;
MongoClient.connect(“mongodb://localhost/test,函数(err,db){
如果(错误)抛出错误;
//进入前10名
db.集合(“账簿”).合计(
[
{“$组”:{
“_id”:“$company”,
“计数”:{“$sum”:1}
}},
{“$sort”:{“count”:-1},
{“$limit”:10}
],函数(错误,结果){
如果(错误)抛出错误;
//查询每个结果并将查询响应映射为URL
异步映射(
结果,
函数(结果、回调){
db.collection(“Books”).find({
“公司”:result.company
}).限制(3).toArray(功能(错误,项目){
result.url=items.map(函数(项){
返回item.url;
});
回调(错误、结果);
})
},
功能(错误、结果){
如果(错误)抛出错误;
//每个结果条目有3个URL
}
);
}
)
});
是的,需要对数据库进行更多的调用,但实际上只有10次,因此不是什么问题

中介绍了此项的实际分辨率。这是一个有希望的“进展中”状态,因此它正在积极地进行工作


一旦解决了这个问题,那么一个聚合语句就变得可行了,因为这样您就可以将初始
$push
中生成的“URL”仅“限制”为三个条目,而不是在事后删除除三个之外的所有条目。

非常感谢。谢谢。解释得很好。