Javascript 如何在mongoDb中找到字段值的最长和最短长度?

Javascript 如何在mongoDb中找到字段值的最长和最短长度?,javascript,mongodb,mapreduce,mongodb-query,mongoid,Javascript,Mongodb,Mapreduce,Mongodb Query,Mongoid,字段的数据类型为字符串。我想找到mongoDB中字段的最长和最短值的长度 我的收藏中总共有500000个文档。您可以使用mongo shell脚本。请注意,它将执行完整的表扫描 function findMinMax() { var max = 0; var min = db.collection.findOne().fieldName.length; db.collection.find().forEach(function(doc)

字段的数据类型为字符串。我想找到mongoDB中字段的最长和最短值的长度


我的收藏中总共有500000个文档。

您可以使用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();
函数findMinMax(){
var max=0;
var min=db.collection.findOne().fieldName.length;
db.collection.find().forEach(函数(doc){
var currentLength=doc.fieldName.length;
如果(当前长度>最大值){
最大值=当前长度;
}
如果(当前长度<分钟){
最小值=电流长度;
}
});
打印(最大值);
打印(分钟);
}
使用
findMinMax();
您可以将函数保存在一个文件中,比如c:\minMax.js,并以

c:\mongodb\bin> mongo dbName < c:\minMax.js
c:\mongodb\bin>mongodbname
注意:您可能需要提供连接到数据库所需的主机名、用户名和密码

c:\mongodb\bin> mongo --host hostName --port portNumber -u userName -p password dbName < c:\minMax.js
c:\mongodb\bin>mongo--主机名--端口号-u用户名-p密码dbName
在现代版本中,MongoDB具有or聚合运算符,您只需执行以下操作:

Class.collection.aggregate([
{“$group”=>{
“_id”=>nil,
“max”=>{“$max”=>{“$strLenCP”=>“$a”},
“min”=>{“$min”=>{“$strLenCP”=>“$a”}
}}
]) 
其中
“a”
是文档中要从中获取最小和最大长度的字符串属性


要输出最小和最大长度,最好的方法是使用一些技巧来保持值

首先,定义一个映射器函数,该函数实际上将从集合中输出单个项以减少负载:

map=Q%{
函数(){
if(此a.length<存储[0])
存储区[0]=此a.长度;
if(this.a.length>存储[1])
存储区[1]=此a.长度;
如果(计数=0)
emit(null,0);
计数++;
}
}
由于这主要是使用一个全局范围的变量来保持最小和最大长度,因此您只需要在发出的单个文档上的
finalize
函数中替换它。没有reduce阶段,但为此定义一个“blank”函数,即使未调用该函数:

reduce=Q%{function(){}
最终确定=Q%{
功能(键、值){
返回{
最小值:存储[0],
马克斯:商店[1]
};
}
}
然后调用mapReduce操作:

Class.map\u reduce(map,reduce).out(内联:1).finalize(finalize).scope(存储:[],计数:0)
因此,所有工作都是在服务器上完成的,而不是通过迭代发送到客户机应用程序的结果。在这样一个小集合上:

{u id:ObjectId(“543e8ee7ddd272814f919472”),“a”:“this”}
{u id:ObjectId(“543e8eeddd2272814f919473”),“a”:“某物”}
{“_id”:ObjectId(“543e8ef6ddd272814f919474”),“a”:“other”}
您会得到如下结果(shell输出,但驱动程序的结果大致相同):

{
“结果”:[
{
“_id”:空,
“价值”:{
“min”:4,
“最大”:9
}
}
],
“timeMillis”:1,
“计数”:{
“投入”:3,
“发射”:1,
“减少”:0,
“产出”:1
},
“好”:1
}

因此,mapReduce允许服务器上的JavaScript处理相当快地完成这项工作,从而减少网络流量。目前,MongoDB没有其他本地方法返回字符串长度,因此服务器上需要进行JavaScript处理。

获取字段的最长值

db.entities.aggregate([{ $match:{ condition   }  },{
  $addFields: {
    "length": { $strLenCP: "$feildName" }
  }},
{ "$sort": { "length": -1 } },
{$limit:1}
])

将{“$sort”:{“length”:-1}}更改为{“$sort”:{“length”:1}}作为字段的最短值

如何将其作为mongo shell脚本运行?因此,当我将函数另存为minMax.js时,是否应该将db.collection.find().forEach(函数(doc){替换为db..find().forEach(函数(doc)?我应该在这里使用我的数据库名称吗?我扩展了这个答案,并将其共享到github cf上。@muistooshort为什么要发出500000个文档更重要。OP只需要最小值和最大值。全局值声明为
JavaScript
,并强制转换为这样。并且只能由mapReduce函数访问。是否足够清楚?@muistooshort MongoDB没有任何其他运算符来返回字符串的长度,因此您需要JavaScript,而mapReduce是“返回”结果的唯一方法。如果有本机内容可能会更好,但这仍然是一个“全局”将一个文档值与另一个文档值进行比较,同样,mapReduce是提供此功能的唯一工具。在一个reducer上敲打500000个文档来完成可以在mapper中完成的工作将是一种黑客行为,而且没有必要,更不用说更多的工作了。引用的JavaScript中没有内部字符串,因此这并不重要。或者也许对于新的mongos,你应该使用“=>”的“istead”和“nil”的“null”istead。再加上db.collections…@AntonLosev是“Ruby”,它使用问题标签所引用的
=>
nil
。因此,mapreduce示例的
Q%
东西也是从“Ruby”在服务器上执行JavaScript的代码。这就是你错过的。明白了,很容易错过)
db.entities.aggregate([{ $match:{ condition   }  },{
  $addFields: {
    "length": { $strLenCP: "$feildName" }
  }},
{ "$sort": { "length": -1 } },
{$limit:1}
])