在集合的键中查找最大数据长度

时间:2017-08-01 15:24:07

标签: javascript mongodb mapreduce

{
  "_id" : ObjectId("59786a62a96166007d7e364dsadasfafsdfsdgdfgfd"),
  "someotherdata" : {
    "place1" : "lwekjfrhweriufesdfwergfwr",
    "place2" : "sgfertgryrctshyctrhysdthc ",
    "place3" : "sdfsdgfrdgfvk",
    "place4" : "asdfkjaseeeeeeeeeeeeeeeeefjnhwklegvds."
  }
}

我的收藏中有成千上万的这些。我需要查看所有其他数据并执行以下操作

  1. 检查它是否存在(在某些记录中我有place1而不是place4)
  2. 查找最长记录(以字符串长度计)
  3. 输出必须如下所示(显示最长的字符数)

    {   
      place1: 123,
      place2: 12,
      place3: 17
      place4: 445
    }
    

    我正在使用Mongodb 3.2.9,因此无法访问新的聚合函数。但我确实有Mongodb shell

    编辑:要明确我希望整个系列中的时间最长。所以可能有1000个文档,但只有一个结果,整个集合中每个字段的长度最长。

2 个答案:

答案 0 :(得分:1)

使用.mapReduce()来减少每个键的最大值:

db.collection.mapReduce(
  function() {
    emit(null,
      Object.keys(this.someotherdata).map(k => ({ [k]: this.someotherdata[k].length }))
       .reduce((acc,curr) => Object.assign(acc,curr),{})
    );
  },
  function(key,values) {
    var result = {};
    values.forEach(value => {
      Object.keys(value).forEach(k => {
        if (!result.hasOwnProperty(k))
          result[k] = 0;
        if ( value[k] > result[k] )
          result[k] = value[k];
      });
    });
    return result;
  },
  { 
    "out": { "inline": 1 },
    "query": { "someotherdata": { "$exists": true } }
  }
)

这基本上发出每个文档的子文档路径中存在的每个键的"length",然后在" reduction"中,每个键的最大"length"是实际上回来了。

请注意,在mapReduce中,您需要放置相同的结构,因为它处理大量文档的方式是减少"逐步批量生产。这就是我们emit数字形式的原因,就像"reduce"函数一样。

在问题中显示的文档上提供此输出。当然,它是" max"当你有更多时,在集合中的所有文档上。

   {
        "_id" : null,
        "value" : {
            "place1" : 25.0,
            "place2" : 26.0,
            "place3" : 13.0,
            "place4" : 38.0
        }
    }

对于感兴趣的人来说,问题的背景实际上是他们无法获得MongoDB 3.4的功能。但是要使用功能可用的.aggregate()来做同样的事情:

db.collection.aggregate([
  { "$match": { "someotherdata": { "$exists": true } } },
  { "$project": {
    "_id": 0,
    "someotherdata": {
      "$map": { 
        "input": { "$objectToArray": "$someotherdata" },
        "as": "s",
        "in": { "k": "$$s.k", "v": { "$strLenCP": "$$s.v" } }
      }
    }
  }},
  { "$unwind": "$someotherdata" },
  { "$group": {
     "_id": "$someotherdata.k",
     "v": { "$max": "$someotherdata.v" }    
  }},
  { "$sort": { "_id": 1 } },
  { "$group": {
    "_id": null,
    "data": {
      "$push": { "k": "$_id", "v": "$v" }
    }    
  }},
  { "$replaceRoot": {
    "newRoot": {
      "$arrayToObject": "$data"   
    } 
  }}
])

输出相同:

{
    "place1" : 25,
    "place2" : 26,
    "place3" : 13,
    "place4" : 38
}

答案 1 :(得分:0)

使用cursor.forEach迭代整个集合。 跟踪 n 值的最长位置(从-1开始,更新找到时更新)。使用print()printjson()

打印出值