【发布时间】:2014-12-11 06:57:40
【问题描述】:
字段的数据类型是字符串。我想在 mongoDB 中找到一个字段的最长和最短值的长度。
我的收藏中总共有 500000 个文档。
【问题讨论】:
标签: javascript mongodb mapreduce mongodb-query mongoid
字段的数据类型是字符串。我想在 mongoDB 中找到一个字段的最长和最短值的长度。
我的收藏中总共有 500000 个文档。
【问题讨论】:
标签: javascript mongodb mapreduce mongodb-query mongoid
您可以使用 mongo shell 脚本。请注意,它将执行全表扫描。
function findMinMax() {
var max = 0;
var min = db.collection.findOne().fieldName.length;
db.collection.find().forEach(function(doc) {
var currentLength = doc.fieldName.length;
if (currentLength > max) {
max = currentLength;
}
if (currentLength < min) {
min = currentLength;
}
});
print(max);
print(min);
}
use <databaseName>
findMinMax();
您可以将函数保存在一个文件中,例如 c:\minMax.js 并运行该文件,
c:\mongodb\bin> mongo dbName < c:\minMax.js
注意:您可能需要提供必要的主机名、用户名、密码才能连接到您的数据库。
c:\mongodb\bin> mongo --host hostName --port portNumber -u userName -p password dbName < c:\minMax.js
【讨论】:
在现代版本中,MongoDB 具有 $strLenBytes 或 $strLenCP 聚合运算符,您可以这样做:
Class.collection.aggregate([
{ "$group" => {
"_id" => nil,
"max" => { "$max" => { "$strLenCP" => "$a" } },
"min" => { "$min" => { "$strLenCP" => "$a" } }
}}
])
"a" 是您想要从中获取最小和最大长度的文档中的字符串属性。
要输出最小和最大长度,最好的方法是使用 mapReduce 并通过一些技巧来保持值。
首先,您定义一个映射器函数,该函数实际上只是要从您的集合中输出单个项目以减少负载:
map = Q%{
function () {
if ( this.a.length < store[0] )
store[0] = this.a.length;
if ( this.a.length > store[1] )
store[1] = this.a.length;
if ( count == 0 )
emit( null, 0 );
count++;
}
}
由于这主要使用全局范围的变量来保持最小和最大长度,因此您只想在发出的单个文档的 finalize 函数中替换它。没有 reduce 阶段,但为此定义一个“空白”函数,即使它没有被调用:
reduce = Q%{ function() {} }
finalize = Q%{
function(key,value) {
return {
min: store[0],
max: store[1]
};
}
}
然后调用mapReduce操作:
Class.map_reduce(map,reduce).out(inline: 1).finalize(finalize).scope(store: [], count: 0)
所以所有工作都在服务器上完成,而不是通过迭代发送到客户端应用程序的结果。在这样的一个小场景中:
{ "_id" : ObjectId("543e8ee7ddd272814f919472"), "a" : "this" }
{ "_id" : ObjectId("543e8eedddd272814f919473"), "a" : "something" }
{ "_id" : ObjectId("543e8ef6ddd272814f919474"), "a" : "other" }
你会得到这样的结果(shell 输出,但对于驱动程序几乎相同):
{
"results" : [
{
"_id" : null,
"value" : {
"min" : 4,
"max" : 9
}
}
],
"timeMillis" : 1,
"counts" : {
"input" : 3,
"emit" : 1,
"reduce" : 0,
"output" : 1
},
"ok" : 1
}
因此,mapReduce 允许服务器上的 JavaScript 处理相当快地完成此操作,从而减少您的网络流量。 MongoDB目前没有其他原生方式返回字符串长度,因此需要在服务器端进行JavaScript处理。
【讨论】:
JavaScript 声明的,并且是这样转换的。并且只有 mapReduce 函数可以访问。够清楚吗?
=> 和nil 的“Ruby”,由问题上的mongoid 标签引用。因此,Q% 的事情也是 mapreduce 示例从“Ruby”代码在服务器上执行 JavaScript。所以这就是你错过的。
用于获取字段的最长值
db.entities.aggregate([{ $match:{ condition } },{
$addFields: {
"length": { $strLenCP: "$feildName" }
}},
{ "$sort": { "length": -1 } },
{$limit:1}
])
将 { "$sort": { "length": -1 } } 更改为 { "$sort": { "length": 1 } } 以获得字段的最短值
【讨论】: