我有一个用户集合,其中进一步有一个“用户订阅”集合,其中还具有“订阅>发布”。
Mongo收藏看起来像这样
/* 1 */
{
"_id" : 1,
"UserSubscriptions" : [
{
"_id" : 1,
"Subscription" : {
"_id" : 1,
"Publication" : {
"_id" : 1,
"Code" : "1MM",
},
},
{
"_id" : 2,
"Subscription" : {
"_id" : 2,
"Publication" : {
"_id" : 2,
"Code" : "2MM",
},
},
{
"_id" : 7,
"Subscription" : {
"_id" : 7,
"Publication" : {
"_id" : 1,
"Code" : "1MM",
},
}
]
}
/* 2 */
{
"_id" : 2,
"UserSubscriptions" : [
{
"_id" : 3,
"Subscription" : {
"_id" : 3,
"Publication" : {
"_id" : 1,
"Code" : "1MM",
}
}
]
}
/* 3 */
{
"_id" : 3,
"UserSubscriptions" : [
{
"_id" : 4,
"Subscription" : {
"_id" : 4,
"Publication" : {
"_id" : 1,
"Code" : "1MM",
}
}
]
}
/* 4 */
{
"_id" : 4,
"UserSubscriptions" : [
{
"_id" : 5,
"Subscription" : {
"_id" : 5,
"Publication" : {
"_id" : 2,
"Code" : "2MM",
}
}
]
}
我正在尝试获取所有“出版物”和计数(用户已订阅订阅计数)。所以从上面的收藏中我想要这样的结果
PublicationCode Count (Number of users)
1MM 3
2MM 2
我尝试了以下MongoDB查询并获得结果
db.runCommand( {
aggregate: "User",
pipeline: [
{$unwind: '$UserSubscriptions'},
{$group: {_id: '$_id',pub: {$addToSet:
'$UserSubscriptions.Subscription.Publication'}}},
{$unwind: '$pub'},
{$group: {_id: '$pub.Code',pub:{$first:'$pub'}, count: {$sum: 1}}},
{$project:{_id:0,"Publication":"$pub","count":1}}
]} )
对应的C#Mongo驱动程序代码为
var unwind = new BsonDocument { { "$unwind", "$UserSubscriptions" } };
var group1 = new BsonDocument
{
{ "$group",
new BsonDocument
{
{ "_id", "$_id"
},
{
"publications", new BsonDocument
{
{
"$addToSet","$UserSubscriptions.Subscription.Publication"
}
}
}
}
}
};
var unwindCode = new BsonDocument { { "$unwind", "$publications" } };
var group2 = new BsonDocument
{
{ "$group",
new BsonDocument
{
{ "_id", "$publications.Code"
},
{
"Publications", new BsonDocument
{
{
"$first","$publications"
}
}
},
{
"NumberOfUsers", new BsonDocument
{
{
"$sum",1
}
}
}
}
}
};
var project = new BsonDocument
{
{
"$project",
new BsonDocument
{
{"_id", 0},
{"Publication","$Publications"},
{"NumberOfUsers", 1},
}
}
};
var pipeline = new[] { unwind, group1, unwindCode, group2, project };
List<BsonDocument> docs= coll.Aggregate<BsonDocument>(pipeline);
结果“计数”在“出版物”文档中正确无误。 但是查询需要一些时间才能返回结果。对于5万名用户记录,这大约需要23秒。
请提出一些改进MongoDB查询性能的方法
(Robo 3T 1.2.1)(MongoDB.Driver 2.4.4)
答案 0 :(得分:0)
主要问题是您需要遍历整个集合(在这种情况下,您不能使用索引来加快处理速度。)
您可以尝试以下代码(它比您的操作少):
db.getCollection('User').aggregate([
{
$unwind: "$UserSubscriptions"
},
{
$group: {
_id:"$UserSubscriptions.Subscription.Publication.Code",
users: {$addToSet: "$_id"}
}
},
{
$project: {"PublicationCode": "$_id", "Count": {$size: "$users"}}
}
])