我有一个很大的歌曲集合,并希望每周获得最多播放歌曲的数组。作为例子:Mongodb Mapreduce加入阵列
{
"_id" : {
"title" : "demons savaites hitas",
"name" : "imagine dragons"
},
"value" : {
"weeks" : [
{
"played" : 56,
"week" : 9,
"year" : 2014
}
]
}
}
它有时会:
{
"_id" : {
"title" : "",
"name" : "top 15"
},
"value" : {
"played" : 1,
"week" : 8,
"year" : 2014
}
}
这是我从被命名的歌曲和新的领域会添加时会添加一个歌曲所有的时间获取数据的集合。没有独特的artistnames或songtitles和集合中的每个文件看起来是这样的:
{
"_id" : ObjectId("530536e3d4ca1a783342f1c8"),
"week" : 8,
"artistname" : "City Shakerz",
"songtitle" : "Love Somebody (Summer 2012 Mix Edit)",
"year" : 2014,
"date" : ISODate("2014-02-19T22:57:39.926Z")
}
我现在想要做的映射缩减其新的一周添加到阵列。它现在覆盖它。 我也注意到当尝试改变为一个数组时,并不是所有的玩家都会使用新的mapreduce进行计数。
新的MapReduce不工作,与周:
map = function() {
if (this.week == 9 && this.year == 2014) emit({title:this.songtitle.toLowerCase(), name:this.artistname.toLowerCase()}, {played:1, week:this.week, year:this.year});
}
reduce = function(k, values) {
var result = {};
result.weeks = new Array();
var object = {played:0, week: 0, year: 0};
values.forEach(function(value) {
object.played += value.played;
object.week = value.week;
object.year = value.year;
});
result.weeks.push(object);
return result;
}
db.songs.mapReduce(map,reduce,{out: {reduce:"played2"}})
这是旧的我使用的是为每周和歌曲集合在一个新的领域:
map = function() {
if (this.week == 10 && this.year == 2014) emit({title:this.songtitle.toLowerCase(), name:this.artistname.toLowerCase(), week:this.week, year:this.year}, {count:1});
}
reduce = function(k, values) {
var result = {count: 0,};
values.forEach(function(value) {
result.count += value.count;
});
return result;
}
db.songs.mapReduce(map,reduce,{out: {merge:"played"}})
我现在得到played2这样来回toplist的信息:
db.played2.find({'_id.week': 9,'_id.year': 2014}).sort(array("value.count" => -1)).limit(50)
以上线可以包括任何错字,因为我使用PHP的MongoClient并需要将其更改为JavaScript语法。
我在做什么错?
你可以包括你的**原始**集合的结构是什么。我的观点是我不认为你想要mapReduce,这可能会有更好的方法。 –
@NeilLunn - 我已经用文档编辑了这些问题以及该集合如何工作。它只是最后播放歌曲的一个长时间的收藏集,所有时间都会添加新歌,大约每秒10个。 –
尝试回答中的聚合语句。聚合管道的运行速度比map reduce快得多,这似乎适合您的预期结果。 –