【问题标题】:MongoDB Query advice for weighted randomized aggregation用于加权随机聚合的 MongoDB 查询建议
【发布时间】:2014-12-11 09:41:10
【问题描述】:

到目前为止,我遇到了选择随机文档的方法,但我的问题有点像泡菜。所以这里是

我有一个集合,其中包含 1000+ 个文档(产品) 假设每个文档都有或多或少的通用格式。为简单起见说它是

{"_id":{},"name":"Product1","groupid":5}

groupid 是一个介于 1 到 20 之间的数字,表示产品属于该组。

现在,如果我的查询 input 类似于 {groupid->weight} 数组,例如 {[{"2":4},{"7":6}] } 并说出另一个参数 n(=10 say) 然后我需要能够选择 4 个随机文档 属于 groupid 2 和 6属于 groupid 7 的随机文档

我能想到的唯一解决方案是运行“m”个子查询,其中 m 是查询输入中的数组长度。 我如何使用可能的 Mapreduce 在 MongoDB 中以一种有效的方式完成此操作。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework database


    【解决方案1】:

    为每个组随机抽取n 文档。

    • groupid 字段对记录进行分组。将groupid 发送为keyrecordvalue
    • 对于每个组,从 values 数组中选择 n 随机文档。

    让,

    var parameter = {"5":1,"6":2}; //groupid->权重,保持为Object。

    成为 map reduce 函数的输入。

    map 函数仅发出我们作为 parameter 提供的那些组 ID。

    var map = function map(){
    if(parameter.hasOwnProperty(this.groupid)){
       emit(this.groupid,this);
     }
    }
    

    reduce函数,对于每个组,根据scope中的parameter对象获取随机记录。

    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带入图片时,需要指定每组的文档数为比例,否则根本不需要该参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-18
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      相关资源
      最近更新 更多