在 collection 的键中查找最大数据长度
Find maximum length of data in keys for the collection
{
"_id" : ObjectId("59786a62a96166007d7e364dsadasfafsdfsdgdfgfd"),
"someotherdata" : {
"place1" : "lwekjfrhweriufesdfwergfwr",
"place2" : "sgfertgryrctshyctrhysdthc ",
"place3" : "sdfsdgfrdgfvk",
"place4" : "asdfkjaseeeeeeeeeeeeeeeeefjnhwklegvds."
}
}
我的 collection 中有数千个这样的东西。我需要查看所有其他数据并执行以下操作
- 检查它是否存在(在某些记录中我有 place1 而不是 place4)
- 找到最长的记录(以字符串长度计)
输出必须如下所示(显示最长的字符数)
{
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()
打印值
{
"_id" : ObjectId("59786a62a96166007d7e364dsadasfafsdfsdgdfgfd"),
"someotherdata" : {
"place1" : "lwekjfrhweriufesdfwergfwr",
"place2" : "sgfertgryrctshyctrhysdthc ",
"place3" : "sdfsdgfrdgfvk",
"place4" : "asdfkjaseeeeeeeeeeeeeeeeefjnhwklegvds."
}
}
我的 collection 中有数千个这样的东西。我需要查看所有其他数据并执行以下操作
- 检查它是否存在(在某些记录中我有 place1 而不是 place4)
- 找到最长的记录(以字符串长度计)
输出必须如下所示(显示最长的字符数)
{
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()