我非常擅长操作mongodb,只能使用简单的find()。但我有一个复杂的结构集合存储在mongodb中,版本是3.2.15。超过1000万条记录。
集合统计的主要结构如下:
{
"_id" : BinData(3,"oQsAvnL1X01YbXCd6X1q1A=="),
"UserId" : BinData(3,"urrg10Znz0moqFize9js+A=="),
... (many unimportant nodes or arrays not included for statistic),
"Pages" : [
{
"Url" : {
"Path" : "http://www.aaaa.com/",
"QueryString" : "?tipid=2C683459F4244C2181EB697DA32AB330"
}
}
]
}
对于Pages:可以为空,也可以是每个UserId的多个值。对于UserId:可以是一条记录,也可以是多条记录。
我的问题是:我怎样才能统计以下值:
我要用mapreduce吗?怎么写这些功能?或者其他任何方式?
答案 0 :(得分:0)
您也可以使用聚合管道。假设您的收藏名称为statistics
。
第一个值:
db.statistics.aggregate([
{$project: {"Pages": 1}},
{$unwind: "$Pages"},
{$project: {"Url": {$concat: ["$Pages.Url.Path", "$Pages.Url.QueryString"]}}},
{$group: {_id: "$Url"}},
{$count: "DistinctUrls"}
]);
第二个值:
db.statistics.aggregate([
{$project: {"UserId": 1, "Pages": 1}},
{$unwind: "$Pages"},
{$project: {"UserId": 1, "Url": "$Pages.Url.Path"}},
{$group: {_id: {"UserID": "$UserId", "Url": "$Url"}},
{$group: {_id: "$_id.UserID", "Pages": {$sum: 1}}}
]);
虽然,给定数据集大小Map-Reduce会表现得更好。
第一个值:
db.statistics.mapReduce(function() {
this.Pages.forEach(function(Page) {
this.emit(Page.Url.Path + Page.Url.QueryString, true);
});
}, function(key, values) {
return true;
}, {
out: 'distinct_urls'
});
db.distinct_urls.count();
第二个值:
db.statistics.mapReduce(function() {
this.Pages.forEach(function(Page) {
this.emit(this.UserId, Page.Url.Path);
});
}, function(key, values) {
var newValue = [];
values.forEach(function(value) {
newValue = newValue.concat(value);
});
return newValue;
}, {
finalize: function(key, values) {
var pages = {};
values.forEach(function(value) {
pages[value] = true;
});
return Object.keys(pages).length;
}
});