Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb组和排序_Mongodb - Fatal编程技术网

Mongodb组和排序

Mongodb组和排序,mongodb,Mongodb,如何翻译以下Sql查询Mongo 从coll中选择a、b、sum(c)csum,其中active=1按a分组,b按a排序 有没有办法用Mongo执行分组和排序查询 db.coll.group( {key: { a:true, b:true }, cond: { active:1 }, reduce: function(obj,prev) { prev.csum += obj.c; }, initial: { csum: 0 }

如何翻译以下
Sql
查询
Mongo

从coll中选择a、b、sum(c)csum,其中active=1按a分组,b按a排序
有没有办法用Mongo执行分组和排序查询

db.coll.group(
       {key: { a:true, b:true },
        cond: { active:1 },
        reduce: function(obj,prev) { prev.csum += obj.c; },
        initial: { csum: 0 }
        });
您可以在MongoDB中执行它,直到MongoDB 2.1中发布为止,对group as in的调用相当慢,因为它使用数据库的JavaScript部分

您可以使用更快的方法计算组数:

如果在a和b上有索引,速度会更快


我建立了一个直方图,我对版本2.2.2所做的是:

answer = db.coll.group(...)
db.histo.insert(answer)
db.histo.find().sort({ field: 1 })
此时,如果您不需要它,只需
db.histo.drop()

您还可以避免使用该变量,并执行以下操作:

db.histo.insert(db.coll.group(...))
db.histo.ensureIndex({ field: 1 })

使用聚合框架,可以执行以下操作:

db.coll.aggregate({
$group:{
_身份证号码:“$a”,
countA:{$sum:1},
sumC:{$sum:$c},
},
$sort:{a:1}
});
但是,如果数据过多,可能会收到以下错误消息:

{
    "errmsg" : "exception: aggregation result exceeds maximum document size (16MB)",
    "code" : 16389,
    "ok" : 0
}
有关SQL到Mongo翻译的更多信息,请参见此处:

受Mongo网站的启发

生成虚拟数据:

> db.stack.insert({a:1,b:1,c:1,active:1})
> db.stack.insert({a:1,b:1,c:2,active:0})
> db.stack.insert({a:1,b:2,c:3,active:1})
> db.stack.insert({a:1,b:2,c:2,active:0})
> db.stack.insert({a:2,b:1,c:3,active:1})
> db.stack.insert({a:2,b:1,c:10,active:1})
> db.stack.insert({a:2,b:2,c:10,active:0})
> db.stack.insert({a:2,b:2,c:5,active:1})
MONGO查询:

> db.stack.aggregate(
... {$match:{active:1}},
... {$group:{_id:{a:"$a", b:"$b"}, csum:{$sum:"$c"}}},
... {$sort:{"_id.a":1}})
结果:

{"result" : [
    {"_id" : {"a" : 1,"b" : 2},"csum" : 3},
    {"_id" : {"a" : 1,"b" : 1},"csum" : 1},
    {"_id" : {"a" : 2,"b" : 2},"csum" : 5},
    {"_id" : {"a" : 2,"b" : 1},"csum" : 13}
],"ok" : 1}

(注意:我将shell结果重新格式化了一点,因此它更具可读性)

mongodb聚合API似乎已经更改。现在你可以做了

db.coll.aggregate([
  {
     $group: { 
        _id: "$a", 
        countA: { $sum: 1}, 
        sumC:{ $sum: "$c"}, 
     }
  },
  {
    $sort:{a:1}
  }
])

请注意aggregate()参数的数组语法。您还可以将things link$match、$limit等添加为该数组的元素。

添加到前面的答案中,如果您希望根据总和(聚合结果)而不是实际列进行排序,可以执行以下操作:

db.your_collection.aggregate([
    {
        $group: {_id: "$your_document_name", count: {$sum: 1}}
    }, 
    {
        $sort: {"count":-1}
    }
])
这相当于以下标准SQL ish语法:

select col_a, count(col_a) as b
from table
group by col_a
order by b desc

我想添加以下查询,作为一个示例,它在两个分组的情况下可能很有用

查询:

db.getCollection('orders').aggregate([
    {$match:{
        tipo: {$regex:"[A-Z]+"}
        }
    },
    {$group:
        { 
            _id:{
                codigo:"1",
                fechaAlta:{$substr:["$fechaAlta",0,10]},
            },
            total:{$sum:1}
        }
    },
    {$sort:
        {"_id":1}
    },
    {$group:
        {
            _id:"$_id.codigo",
            fechasAltas:
            {
                $push:
                {
                    fechaAlta:"$_id.fechaAlta",
                    total:"$total"
                }
            },
            totalGeneral:{$sum:"$total"}
        }
    }
]); 
答复:

{
"_id" : "1",
"fechasAltas" : [ 
    {
        "fechaAlta" : "1940-01-01",
        "total" : 13.0
    }, 
    {
        "fechaAlta" : "2007-05-14",
        "total" : 115.0
    }, 
    {
        "fechaAlta" : "2008-09-30",
        "total" : 58.0
    }, 

    .
    .
    .
],
"totalGeneral" : 50620.0
}       

您可以按照$group$sort的顺序聚合使用$group和$sort。 使用“在前排序”组将不起作用。 考虑下面的例子:

let data = await ABCModel.aggregate([
      {
        $match: { city: { $nin: ['', null] }},
      },
      {
        $group: {
          _id: { $toLower: '$city' }
        },
      },
      { $sort: { _id: 1 } },
    ]);

马吕斯,别理会我的编辑,我一定是出了什么问题,它是你写的!很抱歉这不再有效:“管道阶段规范对象必须只包含一个字段。”@user3690202这是因为聚合现在需要一个对象数组,而不是一个包含多个字段的单个对象。只有组,排序/排序依据在哪里?
{
"_id" : "1",
"fechasAltas" : [ 
    {
        "fechaAlta" : "1940-01-01",
        "total" : 13.0
    }, 
    {
        "fechaAlta" : "2007-05-14",
        "total" : 115.0
    }, 
    {
        "fechaAlta" : "2008-09-30",
        "total" : 58.0
    }, 

    .
    .
    .
],
"totalGeneral" : 50620.0
}       
let data = await ABCModel.aggregate([
      {
        $match: { city: { $nin: ['', null] }},
      },
      {
        $group: {
          _id: { $toLower: '$city' }
        },
      },
      { $sort: { _id: 1 } },
    ]);