MongoDB按顶部字段和数组字段聚合多个组

时间:2017-07-10 07:06:52

标签: mongodb aggregation-framework spring-mongodb

我的收藏将如下所示,

{
"_id" : ObjectId("591c5971240033283736860a"),
"status" : "Done",
"createdDate" : ISODate("2017-05-17T14:09:20.653Z")
"communications" : [ 
    {
        "communicationUUID" : "df07948e-4a14-468e-beb1-db55ff72b215",
        "communicationType" : "CALL",
        "recipientId" : 12345,
        "createdDate" : ISODate("2017-05-18T14:09:20.653Z")
        "callResponse" : {
            "Status" : "completed",
            "id" : "dsd45554545ds92a9bd2c12e0e6436d",
        }
    }
]}
{
"_id" : ObjectId("45sdsd59124003345121450a"),
"status" : "ToDo",
"createdDate" : ISODate("2017-05-17T14:09:20.653Z")
"communications" : [ 
    {
        "communicationUUID" : "45sds55-4a14-468e-beb1-db55ff72b215",
        "communicationType" : "CALL",
        "recipientId" : 1234,
        "createdDate" : ISODate("2017-05-18T14:09:20.653Z")
        "callResponse" : {
            "Status" : "completed",
            "id" : "84fe862f1924455dsds5556436d",
        }
    }
]}
  

目前我正在编写两个聚合查询来实现我的要求,我的查询将在

下面
db.collection.aggregate(
{ $project: {
      dayMonthYear: { $dateToString: { format: "%d/%m/%Y", date: "$createdDate" } },
      status: 1,
}},
{ $group: { 
    _id: "$dayMonthYear",
    Pending: { $sum: { $cond :  [{ $eq : ["$status", "ToDo"]}, 1, 0]} },
    InProgress: { $sum: { $cond :  [{ $eq : ["$status", "InProgress"]}, 1, 0]} },
    Done: { $sum: { $cond : [{ $eq : ["$status", "Done"]}, 1, 0]} },
    Total: { $sum: 1 }
}}

我的输出将是,

{"_id" : "17/05/2017", "Pending" : 1.0, "InProgress" : 0.0, "Done" : 1.0, "Total" : 2.0 }
  

使用上面的查询我可以计算,但我需要根据通信状态找到计数,所以我写了另外一个查询来实现,

db.collection.aggregate(
{"$unwind":"$communications"},
{ $project: {
    dayMonthYear: { $dateToString: { format: "%d/%m/%Y", date: "$createdDate" } },
    communications: 1
}},
{ "$group": { 
    _id: "$dayMonthYear",
    "total_call": { $sum: { $cond :  [{ $or : [ { $eq: [ "$communications.callResponse.Status", "failed"] },
                                                { $eq: [ "$communications.callResponse.Status", "busy"] },
                                                { $eq: [ "$communications.callResponse.Status", "completed"] },
                                                { $eq: [ "$communications.callResponse.Status", "no-answer"] }
                                      ]}, 1, 0 ] }},
    "engaged": { $addToSet: { $cond :  [{ $eq : ["$communications.callResponse.Status", "completed"]}, 
                                                "$communications.recipientId", "null" ]} },
    "not_engaged": { $addToSet: { $cond: [{ $or : [ { $eq: [ "$communications.callResponse.Status", "failed"] },
                                                             { $eq: [ "$communications.callResponse.Status", "busy"] },
                                                             { $eq: [ "$communications.callResponse.Status", "no-answer"] } ]}, 
                                                "$communications.recipientId", "null" ] }}
}},
{ "$project": {
    "_id": 1,
    "total_call": 1,
    "engaged": { "$setDifference": [ "$ngaged", ["null"] ] },
    "not_engaged": { "$setDifference": [ "$not_engaged", ["null"] ] },
}},
{ "$project": {
    "total_call": 1,
    "engaged": { "$size": "$engaged" },
    "not_engaged": { "$size": { "$setDifference": [ "$not_engaged", "$engaged" ] }},
}})

我的输出将是,

{"_id" : "18/05/2017", "total_call" : 2.0, "engaged" : 2, "not_engaged" : 0}
  

使用上面的查询我可以计算,但我想在单个查询中实现它

我正在寻找类似

的输出
{"_id":"17/05/2017", "Pending" : 1.0, "InProgress" : 0.0, "Done" : 1.0, "total_call" : 0, "engaged" : 0, "not_engaged" : 0}
{"_id":"18/05/2017", "Pending" : 0.0, "InProgress" : 0.0, "Done" : 0.0, "total_call" : 2, "engaged" : 2, "not_engaged" : 0}

任何人都可以建议或提供我获得上述结果的好方法。

1 个答案:

答案 0 :(得分:1)

您可以使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css"> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"> <form class="well form-horizontal" action=" " method="post" id="user_edit"> <div class="form-group"> <div class="col-md-8 inputGroupContainer"> <div class="input-group"><span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span> <select name="dob_day" id ="dob_day" class="dob_d js-example-basic-single "> </select><!-- --><select name="dob_month" id ="dob_month" class="dob_m js-example-basic-single "> </select><!-- --><select name="dob_year" id ="dob_year" class=" js-example-basic-single dob_y"> </select> <input type="hidden" name="dob" value="1" /> </div> </div> </div> </form> <script> $(document).ready(function () { var month = [], day = [], year = []; for (var i = 1; i <= 12; i++) { month.push(i); } for (var i = 1; i <= 31; i++) { day.push(i); } for (var i = 1900; i <= (new Date().getFullYear()); i++) { year.push(i); } $.each(day, function (index, d) { $("#dob_day").append("<option>" + d + "</option>"); }); $.each(month, function (index, m) { $("#dob_month").append("<option>" + m + "</option>"); }); $.each(year, function (index, y) { $("#dob_year").append("<option>" + y + "</option>"); }); }); </script>合并$concatArrays&amp; status文件后跟createdDate来计算事件的数量。

$group