Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB,返回集合中每个用户的最近文档_Mongodb_Mapreduce - Fatal编程技术网

MongoDB,返回集合中每个用户的最近文档

MongoDB,返回集合中每个用户的最近文档,mongodb,mapreduce,Mongodb,Mapreduce,寻找与Postgres的Distinct On类似的功能 有一个文档集合{user\u id,current\u status,date},其中status只是文本,date是日期。我还在蒙哥的早期阶段,我还没有找到最好的做事方式 mapreduce是这里最好的解决方案吗?map会发出所有信息,reduce会记录最新的一个,还是有一个内置的解决方案而不拉出mr?有一个,但是我不确定这是您需要的。Distinct是一种“查询”命令,对于大量用户,您可能希望不实时地汇总数据 Map Reduce可能

寻找与Postgres的Distinct On类似的功能

有一个文档集合{user\u id,current\u status,date},其中status只是文本,date是日期。我还在蒙哥的早期阶段,我还没有找到最好的做事方式

mapreduce是这里最好的解决方案吗?map会发出所有信息,reduce会记录最新的一个,还是有一个内置的解决方案而不拉出mr?

有一个,但是我不确定这是您需要的。Distinct是一种“查询”命令,对于大量用户,您可能希望不实时地汇总数据

Map Reduce可能是一种方法

映射阶段:您的
将只是一个ID。您的
将类似于以下
{当前状态:'blah',日期:1234}

减少阶段:给定一个值数组,您将获取最近的值并仅返回它

为了使这项工作达到最佳效果,您可能需要查看1.8.0中的新功能。这个将允许您仅处理新数据,而不是重新处理整个状态集合

另一种方法是构建“最近”的集合,并将状态插入绑定到该集合。因此,当您为用户插入新状态时,您将更新其“最近”状态


根据此功能的重要性,您可以同时执行这两项操作。

当前的解决方案似乎运行良好

map = function () {emit(this.user.id, this.created_at);}

//We call new date just in case somethings not being stored as a date and instead just a string, cause my date gathering/inserting function is kind of stupid atm

reduce = function(key, values) { return new Date(Math.max.apply(Math, values.map(function(x){return new Date(x)})))}


res = db.statuses.mapReduce(map,reduce);

实现相同结果的另一种方法是使用
group
命令,这是一种mr快捷方式,可用于聚合特定键或一组键。 在您的情况下,其内容如下:

db.coll.group({ key : { user_id: true },
                reduce : function(obj, prev) { 
                           if (new Date(obj.date) < prev.date) { 
                             prev.status = obj.status; 
                             prev.date = obj.date; 
                           }
                         },
              initial : { status : "" }
}) 
db.coll.group({key:{user\u id:true},
reduce:函数(obj,prev){
如果(新日期(目标日期)<上一日期){
prev.status=obj.status;
prev.date=obj.date;
}
},
初始:{状态:}
}) 

但是,除非您的固定用户数量非常少,否则我坚信更好的解决方案是,如前所述,保留一个单独的集合,只包含每个用户的最新状态消息。

谢谢,我认为这两种方法都值得研究,特别是re-reduce。考虑到最近的收集方法,这似乎会给插入过程增加很多开销,这是我希望避免的,因为这是我使用mongo的部分原因。我需要用我为每个id插入的id搜索/删除状态。虽然这应该不会很快,因为它已索引且集合较小,但mongo确实存在锁定整个集合以进行删除的“问题”,因此“似乎”这将是一个巨大的折衷。您可以很快地执行
upsert
upsert
是“如果存在,更新或创建”。因此没有删除或附加查询。在JS中,这看起来像下面的
db.most_-recent.update({u-id:user_-id},{status:“blah”},false,true)
,检查语言驱动程序的“upsert”。是的,我记得upsert在我最后一次评论后不久。因为我有一个用户群增长得相当快,我认为最近的收集是最好的方式来做到这一点,所以我正在朝这个方向发展。谢谢你的回答,谢谢你的建议。不过,由于group不能与sharding一起使用,我将避免使用这个解决方案。