我有一个这样的集合:
{
_id: ObjectId('534343df3232'),
date: ISODate('2016-01-08T00:00:00Z'),
item_type: "book",
book_id: ObjectId('534343df3232fdf'),
user_id: ObjectId('534343df3232fdf23'),
rating: 6
},
{
_id: ObjectId('534343df3232'),
date: ISODate('2016-01-05T00:00:00Z'),
item_type: "movie",
movie_id: ObjectId('534343df3232fdf'),
user_id: ObjectId('534343df3232fdfa'),
rating: 5
},
{
_id: ObjectId('534343df3232'),
date: ISODate('2016-01-010T00:00:00Z'),
item_type: "song",
song_id: ObjectId('534343df3232fdf'),
user_id: ObjectId('534343df3232fdf13'),
rating: 9
}
每位用户每天每项只能评分一次。
我想检查一下选择用户和项目之间的评分如何变化。我只需要每本书/电影/歌曲的第一个和最后一个评级。
我不知道如何以最有效的方式做到这一点。
就目前而言,我正在检索所有用户的所有评级,然后使用PHP解析它们。
db.ratings.find({user_id:{$in:[...]}, $or:[book_id:{$in:[...]}, song_id:{$in:[...]}, movie_id:{$in:[...]}, ], date:{$gte:.., $lte..} });
这显然效率不高但我不知道如何处理这种情况。
答案 0 :(得分:1)
您可以使用mongodb https://jsfiddle.net/djs0m63q/执行此操作。因此,首先您需要过滤日期范围,用户选择和项目选择(查询部分)的数据。然后逐项(地图部分)和每个项目选择具有相应评级的第一天和最后一天(减少部分)。
尝试以下查询:
var query = {
user_id: {$in:[...]}
date: { $gte: dateFrom, $lt:dateTo},
$or: [
{book_id: {$in:[...]}},
{song_id:{$in:[...]}},
{movie_id:{$in:[...]}}
]
}
var map = function () {
emit(this.item_type, {
first : {rating: this.rating, date: this.date},
last: {rating: this.rating, date: this.date}
})
}
var reduce = function (key, values) {
var res = values[0];
for (var i=1; i<values.length; i++ ) {
if (values[i].first.date < res.first.date)
res.first = values[i].first;
if (values[i].last.date > res.last.date)
res.last = values[i].last;
}
return res;
}
db.collection.mapReduce( map , reduce , { out: { inline : true }, query: query } )