【发布时间】:2014-07-28 15:40:52
【问题描述】:
你能帮我把这个 SQL 查询转换成 MongoDB 吗?
SELECT CHAR_LENGTH(field), count(distinct field2), count(*)
FROM table GROUP BY CHAR_LENGTH(field)
提前致谢!
【问题讨论】:
标签: javascript mongodb mapreduce mongodb-query
你能帮我把这个 SQL 查询转换成 MongoDB 吗?
SELECT CHAR_LENGTH(field), count(distinct field2), count(*)
FROM table GROUP BY CHAR_LENGTH(field)
提前致谢!
【问题讨论】:
标签: javascript mongodb mapreduce mongodb-query
还没有:https://jira.mongodb.org/browse/SERVER-5319,因此即使 MongoDB 知道长度,它目前也无法实际提供给您。
目前最好的方法是将strlen作为整数保存在另一个字段中,然后对其进行分组。
【讨论】:
MapReduce 是目前的方法,因为目前没有其他方法可以评估字符串的长度,您需要 JavaScript 评估函数来执行此操作:
db.collection.mapReduce(
function() {
emit( this.field.length, { "field2": [this.field2], "count": 1 } );
},
function(key,values) {
var reduced = { "field2": [], "count": 0 };
values.forEach(function(value) {
value.field2.forEach(function(field2) {
if ( reduced.field2.indexOf(field2) == -1 )
reduced.field2.push(field2);
});
reduced.count += value.count;
});
return reduced;
},
{
"finalize": function(key,value) {
var output = { "field2count": 0, "count": value.count };
value.field2.forEach(function(field2) {
output.field2count += 1
});
return output;
},
"out": { "inline": 1 }
}
)
因此,由于可以使用标准 JavaScript 函数,您可以在“字段”中获取字符串的长度并将其作为分组键发出。
为了获得另一个“field2”的“不同”计数以及该分组中的总计数,“map”和“reduce”函数中“value”部分的处理方式很重要.
这是人们经常忽略 mapReduce 的部分,因为实际上可以多次调用“reducer”。因此,例如,如果您发出 100 个或更多具有相同值的“键”,那么“reducer”不一定会同时处理它们。它可能只调用其中的一些,应用reduce函数,然后“重新排队”从“reduce”返回的文档,以针对具有相同值的其他“keys”或之前已经存在的其他“keys”进行进一步迭代“减少”。
这就是处理大数据的方式,reducer 将继续这样做,直到同一个键只存在一个值。这就是为什么在“mapper”和“reducer”中发出的“values”的“signatures”需要相同的原因。
除了“累加”“字符串长度”键的出现次数之外,“映射器”通过检查该值是否已存在于数组中,将“field2”数组缩减为仅不同的值。
这就是“finalize”函数的用武之地。一旦文档被缩减,“field2”值(当前是一个数组)将转换为它的“lenght”,从而返回“distinct count”。
如果这里有一个可用于聚合框架的“长度”函数将是“不错的”,但由于目前还没有,因此您可以在此处使用 mapReduce。
【讨论】: