到目前为止,我已经遇到了选择随机文档的方法,但我的问题更多的是一个泡菜。所以这里去了
我有一个包含 1000 + 文件(产品)的集合 说每个文档都有一个或多或少的通用格式。为简单起见,它是
{"_id":{},"name":"Product1","groupid":5}
groupid是1到20之间的数字,表示该产品属于该组。
现在,如果我的查询输入类似于{groupid-> weight}的数组,例如 {[{" 2":4},{& #34; 7":6}]} 并说出另一个参数 n(= 10说)然后我需要能够选择 4个随机文档属于groupid 2和属于groupid 7的 6个随机文档。
我能想到的唯一解决方案就是跑步' m'子查询,其中m是查询输入中的数组长度。 如何使用Mapreduce在MongoDB中实现这种高效的方式。
答案 0 :(得分:1)
为每个小组挑选n
份随机文件。
groupid
字段对记录进行分组。将groupid
作为key
发出
以及record
为value
。n
数组中选择values
个随机文档。让,
var parameter = {"5":1,"6":2};
// groupid-> weight,将其保存为Object。
是地图缩小功能的输入。
map
函数,仅发出我们提供为parameter
的组ID。
var map = function map(){
if(parameter.hasOwnProperty(this.groupid)){
emit(this.groupid,this);
}
}
每个组的reduce
函数根据parameter
中的scope
对象获取随机记录。
var reduce = function(key,values){
var length = values.length;
var docs = [];
var added = [];
var i= 1;
while(i<=parameter[key]){
var index = Math.floor(Math.random()*length);
if(added.indexOf(index) == -1){
docs.push(values[index]);
added.push(index);
i++;
}
else{
i--;
}
}
return {result:docs};
}
通过在范围内传递parameter
对象来调用集合上的map reduce。
db.collection.mapReduce(map,
reduce,
{out: "sam",
scope:{"parameter":{"5":1,"6":2,"n":10}}})
获取转储输出:
db.sam.find({},{"_id":0,"value.result":1}).pretty()
当您将参数n
放入图片时,您需要指定每个组的文档数量作为比率,否则根本不需要该参数。