获取每个条件的第一个和最后一个值

时间:2016-01-12 17:07:14

标签: 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'),
    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..}  });

这显然效率不高但我不知道如何处理这种情况。

1 个答案:

答案 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 } )