Mongodb 获取每个条件的第一个和最后一个值
我有这样的收藏:Mongodb 获取每个条件的第一个和最后一个值,mongodb,Mongodb,我有这样的收藏: { _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')
{
_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..} });
这显然不够有效,但我不知道如何处理这个问题。您可以使用mongodb来处理。因此,首先需要根据日期范围、用户选择和项目选择(查询部分)过滤数据。然后按项目分组(地图部分),为每个项目选择第一天和最后一天以及相应的评分(减少部分) 请尝试以下查询:
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 } )
var查询={
用户id:{$in:[…]}
日期:{$gte:dateFrom,$lt:dateTo},
$or:[
{book_id:{$in:[…]}},
{song_id:{$in:[…]}},
{movie_id:{$in:[…]}
]
}
var map=函数(){
emit(this.item_类型,{
第一:{评级:this.rating,日期:this.date},
最后:{评级:this.rating,日期:this.date}
})
}
var reduce=函数(键、值){
var res=数值[0];
对于(var i=1;i res.last.date)
res.last=值[i]。last;
}
返回res;
}
mapReduce(map,reduce,{out:{inline:true},query:query})
很抱歉,我可能没有解释清楚,我所说的“min”和“max”是指:日期期间内距离边缘最近的值(即第一个值和最后一个值),因为有些日子可能没有评级。这就是我被卡住的地方,因为开始/结束日期可能不准确。@512banque抱歉误解。我已经更新了我的答案。