我有一個很大的歌曲集合,並希望每週獲得最多播放歌曲的數組。作爲例子: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快得多,這似乎適合您的預期結果。 –