2012-10-03 95 views
2

这个问题有两个部分。收集结构是:MongoDB聚合查询相当于PostsgreSQL

_id:MongoID,
AGENT_ID:字符串,
结果:字符串,
created_on:ISO日期,
......等领域......一个

部分:
期望的输出:每个agent_id和结果组合的一个结果,其计数为:使用PostgreSQL的等效SQL的TUPLE表示。

("1234", "Success", 4), 
("1234", "Failure", 4), 
("4567", "Success", 3), 
("7896", "Failure", 2), 
..... 

SELECT agent_id, result, count(*) 
FROM table 
GROUP BY agent_id, result 
HAVING created_on >= now()::date; 

我想出了下面的mongo查询....我想我有一个概念或语法错误。该文档声称使用$匹配early in the pipeline:,但尽管$匹配限制了查询,当我自己运行它时,只要添加$组,我就可以获得许多结果。另外,我似乎无法理解如何组合多个领域。我如何编辑下面的查询来获得像上面的SQL查询的结果?

db.collection.aggregate(
    { $match : 
    { created_on: 
     { $gte: new Date('08-13-2012') //some arbitrary date 
    } 
    }, $group: 
    { _id:"$agent_id" }, 
    $project: 
    {_id:0, agent_id:1, result:1} 
}) 

第2部分) 第一个结果集是足够的,但不是最优的。在PostgreSQL我可以实现的结果集,如:

("1234", { "Success", "Failure" }, { 4, 3 }), 
("4567", { "Success", "Failure" }, { 3, 0 }), 
("7896", { "Success", "Failure" }, { 0, 2 }) 

我可与阵列数据类型和函数set_to_array(自定义功能)为此在PostgreSQL。在PG特定的SQL是:

SELECT agent_id, set_to_array(result), set_to_array(count(*)) 
FROM table 
GROUP BY agent_id, result 
HAVING created_on >= now()::date; 

相信MongoDB中的等效数据结构类似于:

[ 
    { "1234", [ { "success": 4 }, { "failure": 4 } ] }, 
    { "4567", [ { "success": 3 }, { "failure": 0 } ] }, 
    { "7896", [ { "success": 0 }, { "failure": 0 } ] } 
] 

是否有可能实现与mongodb的总框架,这些期望的压缩结果?

回答

3

在这里你去:

创建一些测试数据:

db.test.insert({AGENT_ID: “1234”,结果是: “失败”,created_on:新的Date()}) ; db.test.insert({agent_id:“1234”,result:“Success”,created_on:new Date()}); db.test.insert({agent_id:“1234”,result:“Failure”,created_on:new Date()}); db.test.insert({agent_id:“1234”,result:“Success”,created_on:new Date()}); db.test.insert({agent_id:“1234”,result:“Failure”,created_on:new Date()}); db.test.insert({agent_id:“1234”,result:“Success”,created_on:new Date()}); db.test.insert({agent_id:“1234”,result:“Success”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Success”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Success”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Success”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Success”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Failure”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Failure”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Failure”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Failure”,created_on:new Date()}); db.test。insert({agent_id:“1324”,result:“Failure”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Failure”,created_on:new Date()}); db.test.insert({agent_id:“1324”,result:“Failure”,created_on:new Date()});

db.test.aggregate(
    { 
    $match:{ /* filter out the things you want to aggregate */ 
     created_on:{$gte:new Date(1000000)} 
    } 
    }, 
    { 
    $group: {_ 
     _id: { /* the things you want to group on go in the _id */ 
     agent_id:"$agent_id", 
     result:"$result" 
     }, 
     count:{$sum:1} /* simple count */ 
    } 
    }, 
    { 
    $project: { /* take the id out into the separate fields for your tuple. */ 
     _id:0, 
     agent_id:"$_id.agent_id", 
     result:"$_id.result", 
     count:"$count" 
    } 
    }); 

给出:

{ 
"result" : [ 
    { 
     "count" : 7, 
     "agent_id" : "1324", 
     "result" : "Failure" 
    }, 
    { 
     "count" : 4, 
     "agent_id" : "1324", 
     "result" : "Success" 
    }, 
    { 
     "count" : 4, 
     "agent_id" : "1234", 
     "result" : "Success" 
    }, 
    { 
     "count" : 3, 
     "agent_id" : "1234", 
     "result" : "Failure" 
    } 
], 
"ok" : 1 
} 

添加部2 - 非常相似部分1,但计数是一个比较复杂;基本上你只计算,如果它符合你想要什么来算:

db.test.aggregate(
    { 
    $match: { 
     created_on: {$gte:new Date(1000000)} 
    } 
    }, 
    { 
    $group: { 
     _id: { 
     agent_id:"$agent_id" 
     }, 
     failure: { 
     $sum:{ 
      $cond:[ 
      {$eq:["$result","Failure"]}, 
      1, 
      0 
      ] 
     } 
     }, 
     success: { 
     $sum: { 
      $cond:[ 
      {$eq:["$result","Success"]}, 
      1, 
      0 
      ] 
     } 
     } 
    } 
    }, 
    { 
    $project: { 
     _id: 0, 
     agent_id: "$_id.agent_id", 
     failure: "$failure", 
     success: "$success" 
    } 
    }); 

给出:

{ 
"result" : [ 
    { 
     "failure" : 7, 
     "success" : 4, 
     "agent_id" : "1324" 
    }, 
    { 
     "failure" : 3, 
     "success" : 4, 
     "agent_id" : "1234" 
    } 
], 
"ok" : 1 
} 
+0

是否有可能放松,以得到一个“总计”?我能够为每个结果添加小计(失败和成功的总和),但我不确定是否生成一条记录,可以在查询本身中总结所有代理的成功和失败。 – Ketema

+0

你的意思是在同一个查询中,还是在一个新的查询中? –

+0

如果结果可能在同一个查询中有一个总计,那么它会很有趣,但不知道这是否可能。 – Ketema