Mongodb:根据需求过滤记录后,如何获得原始的Json结构?

时间:2015-08-05 22:01:31

标签: mongodb aggregation-framework

我是mongodb的新手。

我在集合中有一个Json文档,如:

{
    "_id" : ObjectId("55abf32f358e3aca807f0e6a"),
    "usercbid" : 1995492.0000000000000000,
    "defaultnotifytype" : {
        "status" : true,
        "alert" : true,
        "action" : true
    },
    "calendar" : {
        "alert" : 2468.0000000000000000,
        "action" : 13579.0000000000000000,
        "status" : 123456.0000000000000000
    },
    "assignment" : [ 
        {
            "orgid" : {
                "service" : "AVPN",
                "adminemail" : "pl9129@att.com",
                "notifytype" : {
                    "status" : true,
                    "alert" : true
                },
                "keytype" : "MCN",
                "KeyValue" : "SK1383"
            }
        }, 
        {
            "orgid" : {
                "KeyValue" : "DD3342",
                "service" : "<all>",
                "keytype" : "MCN"
            }
        }, 
        {
            "orgid" : {
                "notifytype" : {
                    "optout" : true
                },
                "keytype" : "MCN",
                "keyvalue" : "<all>",
                "service" : "MVPN"
            }
        }, 
        {
            "order" : {
                "date" : "2015-03-15",
                "adminemail" : "abc.com",
                "notifytype" : {
                    "alert" : true
                },
                "id" : 123456.0000000000000000
            }
        }, 
        {
            "order" : {
                "id" : 135246.0000000000000000,
                "date" : "2015-03-17",
                "adminemail" : "abc.com"
            }
        }
    ]
}

我想在以下条件下过滤json文档:

var result =  db.subscription.aggregate(
    [ { $unwind: "$assignment" }
      , {$match : {$or:
          [
             {
              "assignment.order.id" : 123456          
             },
             {
                       "assignment.orgid.keytype" : { $in: ["MCN"]}
                       ,"assignment.orgid.KeyValue" : { $in: ["<all>","SK1383"]}
                       ,"assignment.orgid.service" : { $in: ["<all>","AVPN"]}          
             }
          ]
        }
      }

  ,{$group: {_id: "$_id", assignment: {$push: "$assignment"}}}  
    // ,{$project : { usercbid : $usercbid, defaultnotifytype : 1, calendar : 1, assignment: 1} }

    ]
 )
printjson(result);

以上查询的结果是:

{
    "result" : [        
        {
            "_id" : ObjectId("55abf32f358e3aca807f0e6a"),
            "assignment" : [
                {
                    "orgid" : {
                        "service" : "AVPN",
                        "adminemail" : "pl9129@att.com",
                        "notifytype" : {
                            "status" : true,
                            "alert" : true
                        },
                        "keytype" : "MCN",
                        "KeyValue" : "SK1383"
                    }
                },
                {
                    "order" : {
                        "date" : "2015-03-15",
                        "adminemail" : "pl9129@att.com",
                        "notifytype" : {
                            "alert" : true
                        },
                        "id" : 123456
                    }
                }
            ]
        }
    ],
    "ok" : 1
}

但我的最终结果丢失了以下原始内容:

"usercbid" : 1995492.0000000000000000,
    "defaultnotifytype" : {
        "status" : true,
        "alert" : true,
        "action" : true
    },
    "calendar" : {
        "alert" : 2468.0000000000000000,
        "action" : 13579.0000000000000000,
        "status" : 123456.0000000000000000
    },

如何将原始内容附加到过滤后的记录上?

谢谢,

1 个答案:

答案 0 :(得分:0)

$Fisrt是帮助您获得所需输出的运算符。 当您执行$Group时,$ Group管道运算符的结果仅包含在$ Group管道运算符中指定的那些字段。

因此,从您的查询中我们可以注意到您正在基于“_Id”进行分组,并且您只选择“赋值”键字段,因此该组管道运算符的OUTPUT将仅包含那两个文件(“_ ID”和“任务”)。

为了确保其他人遗漏了feilds(usercbid,defaultnotifytype,calendar)成为$ Group管道输出的一部分,我们需要使用$First在Group管道中明确提及,如下所示:

{ $group: { _id: "$_id", assignment: {$push: "$assignment"}, 
                   usercbid : { $first : "usercbid"} , 
                   defaultnotifytype : { $first : "defaultnotifytype" } , 
                   calendar : { $first : "calendar"} 
           }
}

$First返回将表达式应用于按键共享同一组的一组文档中的第一个文档所产生的值。

请检查以下查询,它将帮助您获取所需的输出:

var result =  db.subscription.aggregate(
    [   { $unwind: "$assignment" }
      , { $match : {$or:
          [
             {
              "assignment.order.id" : 123456          
             },
             {
                       "assignment.orgid.keytype" : { $in: ["MCN"]}
                       ,"assignment.orgid.KeyValue" : { $in: ["<all>","SK1383"]}
                       ,"assignment.orgid.service" : { $in: ["<all>","AVPN"]}          
             }
          ]
        }
      }

  ,{ $group: { _id: "$_id", assignment: {$push: "$assignment"}, 
               usercbid : { $first : "usercbid"} , 
               defaultnotifytype : { $first : "defaultnotifytype" } , 
               calendar : { $first : "calendar"} 
             }
   }  

    ]
 ).pretty();