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

Find maximum length of data in keys for the collection

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

我的 collection 中有数千个这样的东西。我需要查看所有其他数据并执行以下操作

  1. 检查它是否存在(在某些记录中我有 place1 而不是 place4)
  2. 找到最长的记录(以字符串长度计)

输出必须如下所示(显示最长的字符数)

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

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

编辑:明确地说,我想要整个 collection 中最长的。因此,可能有 1000 个文档,但整个 collection 中每个字段的长度最长的结果只有一个。

为此使用 .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 中,您需要输出与输入的结构相同的结构,因为它处理大量文档的方式是 "reducing" 逐步分批处理。这就是为什么我们以数字形式 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
}

使用cursor.forEach 遍历集合。 跟踪最长的 placen 值(从 -1 开始,发现更大时更新)。使用 print()printjson()

打印值