比较mongodb中不同数组的两个字段

时间:2015-04-14 12:03:41

标签: mongodb

我希望有人能帮助我解决话题...... 我有一个基于"门票,任务和Comentaries(Coms)"的mongoDB查询。 sctructure,Tickets数组通常包含Tasks数组和Coms数组,所以我需要解开它们。我的代码是:

db.tickets.aggregate([
    {$unwind : "$Coms" },
    {$match:{
        'Tsks.Sts': 'Closed', //Status: tasks which are closed
        'Coms.TicTskId': {$eq: '$Tsks._id'},**
        'Coms.Typ':'CloseTask'

        }},

    {$project:{
        _id:0,
        'Tsks._id':1,
        'Tsks.Sts':1,
        'Tsks.DueDat':1,
        'Nms.Org':1,
        'Nms.Cmp':1,
        'Nms.Wkg':1,    
        'Coms.Typ':1,
        'Coms.Msg': 1,
        'Coms.TicTskId':1
        }},

    {$unwind : "$Tsks" },
    {$match:{$and:[{
        'Tsks.Sts': 'Closed',
        'Tsks.DueDat': {$ne: null},
        'Tsks._id':{$gt:0}
        }]}},

    {$group:
        {_id:{Org:'$Nms.Org',Cmp:'$Nms.Cmp',Wkg:'$Nms.Wkg', DueDate:'$Tsks.DueDat', CurTskId: '$Tsks._id',Type:'$Coms.Typ',Msg: '$Coms.Msg', TicTskId: '$Coms.TicTskId'},
        Total_Closed:{$sum:1},
        }},

    {$project:{
        Total_Closed : 1,
        Comparation: {$cmp: [ '$CurTskId', '$TicTskId']},
        Equal: {$eq: [ "$CurTskId", "$TicTskId"]},
        }},
        { 
             $sort : {CurEntNme:-1,Org: 1,Cmp : 1 ,Wkg: 1 } 
          }

     ])

我试图展示一组需要遵循这些特征的任务:

    "Sts":"Closed", --> Status should be Closed
    'Tsks.DueDat': {$ne: null}, --> Tasks DueDate shouldn't be null
    'Coms.Typ':'CloseTask', --> Coments type should be "CloseTask"
    'Coms.TicTskId' == '$Tsks._id' --> Comments ID should be as same as Tasks ID

我的主要问题是,我无法找到通过所有这些分组条件得到唯一值的方法,我的意思是,我可以看到所有条件,除了最后一个,当ID和#等于。我只想看到所有iqual,但是如果它们相同或不相同,则该查询将返回两者。例如,我得到一个结果:

result:
  [item]
     _id:
       Org--> Organization
       Company --> Organization 1
       Wkg --> WKG 1
       DueDate --> 2015-04-10 15:00:00.000Z
       CurTskId --> 7
       Type --> CloseTask
       Msg --> these is close
       TicTskId --> 1
   Total_Closed --> 1
   Comparation --> 0 
   Equal --> true 
  

比较不应该是0因为CurTskId和TicTskId不是   类似

     

Equal不应该是真的,因为CurTskId和TicTskId不相似

一个Ticket数据库结构如下所示:

>(1) 12000000        {7 fields}          Object
    _id              12000000             Int64
    TicId            1001                 Int32
    OrgId            2                    Int32
    Sts              Closed               String
   >Nms              {3 fields}           Object
    Cmp              Organization 1       String
    Org              Organization         String
    Wkg              Workgroup            String
  >Tsks              {3 fields}           Object
    _id              1                    Int32
    Sts              Closed               String
    DueDat           2015-04-10           Date
  >Coms              {3 fields}           Object
   TicTskId          7                    Int32
   Typ               CloseTask            String
   Msg               these is close       String

我希望我能以最好的方式解释我的问题,对不起,如果我的英语不是很好。

提前致谢。

1 个答案:

答案 0 :(得分:0)

根据您问题中的数据,假设您拥有以下文档架构和数据:

/* 0 */
{
    "_id" : 12000000,
    "TicId" : 1001,
    "OrgId" : 2,
    "Sts" : "Closed",
    "Nms" : [ 
        {
            "Cmp" : "Organization 1",
            "Org" : "Organization",
            "Wkg" : "Workgroup"
        }
    ],
    "Tsks" : [ 
        {
            "_id" : 1,
            "Sts" : "Closed",
            "DueDat" : ISODate("2015-04-10T00:00:00.000Z")
        }
    ],
    "Coms" : [ 
        {
            "TicTskId" : 1,
            "Typ" : "CloseTask",
            "Msg" : "these is close"
        }
    ]
}

要进行比较$match管道中两个字段的聚合是不可能的,但是解决方法是通过$project操作将数据存储在管道中的其他字段中时设置条件这样您就可以使用isComsTsksEqual字段进行快速真相检查。这种类型的查询会超级快。正如您在上面的测试文档中看到的那样,"Tsks._id"等于" Coms.TicTskId"因此,额外的isComsTsksEqual字段变为true,您现在可以在$match运算符中使用该字段。以下聚合管道演示了这一点:

db.tickets.aggregate([
    {
        "$project": {
            "TicId": 1,
            "OrgId": 1,
            "Sts": 1,
            "Nms": 1,
            "Tsks": 1,
            "Coms": 1,
            "TsksComp": "$Tsks._id"            
        }
    },
    {
        "$project": { 
            "TicId": 1,
            "OrgId": 1,
            "Sts": 1,
            "Nms": 1,
            "Tsks": 1,
            "Coms": 1, 
            "isComsTsksEqual": { 
                "$eq" : [ "$Coms.TicTskId", "$TsksComp" ] 
            }
        }
    },  
    {
        "$unwind": "$Tsks"
    },
    {
        "$unwind": "$Coms" 
    },    
    {
        "$match": {
            "Tsks.Sts": "Closed",             
            "Coms.Typ": "CloseTask",
            "isComsTsksEqual": true
        }
    }
]);

这将返回

/* 0 */
{
    "result" : [ 
        {
            "_id" : 12000000,
            "TicId" : 1001,
            "OrgId" : 2,
            "Sts" : "Closed",
            "Nms" : [ 
                {
                    "Cmp" : "Organization 1",
                    "Org" : "Organization",
                    "Wkg" : "Workgroup"
                }
            ],
            "Tsks" : {
                "_id" : 1,
                "Sts" : "Closed",
                "DueDat" : ISODate("2015-04-10T00:00:00.000Z")
            },
            "Coms" : {
                "TicTskId" : 1,
                "Typ" : "CloseTask",
                "Msg" : "these is close"
            },
            "isComsTsksEqual" : true
        }
    ],
    "ok" : 1
}

不确定您的聚合目标是什么,但您可以通过整合上述内容来修改您当前的聚合管道:

db.tickets.aggregate([
    {
        "$project": {
            "TicId": 1,
            "OrgId": 1,
            "Sts": 1,
            "Nms": 1,
            "Tsks": 1,
            "Coms": 1,
            "TsksComp": "$Tsks._id"            
        }
    },
    {
        "$project": { 
            "TicId": 1,
            "OrgId": 1,
            "Sts": 1,
            "Nms": 1,
            "Tsks": 1,
            "Coms": 1, 
            "isComsTsksEqual": { 
                "$eq" : [ "$Coms.TicTskId", "$TsksComp" ] 
            }
        }
    },  
    {
        "$unwind": "$Tsks"
    },
    {
        "$unwind": "$Coms" 
    }, 
    {
        "$unwind": "$Nms" 
    },
    {
        "$match": {
            "Tsks.Sts": "Closed",             
            "Coms.Typ": "CloseTask",
            "Tsks._id": { "$gt": 0 },
            "Tsks.Sts": "Closed",
            "Tsks.DueDat": { "$ne": null },
            "isComsTsksEqual": true
        }
    },
    {
        "$group": {
            "_id": {
                "Org": "$Nms.Org",
                "Cmp": "$Nms.Cmp",
                "Wkg": "$Nms.Wkg", 
                "DueDate": "$Tsks.DueDat", 
                "CurEntNme": "$OpnPrps.CurEntNme", 
                "CurTskId": "$Tsks._id",
                "Type": "$Coms.Typ",
                "Msg": "$Coms.Msg", 
                "TicTskId": "$Coms.TicTskId"
            },
            "Total_Closed": {
                "$sum": 1
            }
        }
    }/*,
    {
        "$project": {
            "Total_Closed": 1,
            "Comparison": { 
                "$cmp": [ "$CurTskId", "$TicTskId" ]
            },
            "Equal": {
                "$eq": [ "$CurTskId", "$TicTskId" ]
            },
        }
    }*/,
    { 
        "$sort": {
            "CurEntNme": -1,
            "Org": 1,
            "Cmp": 1,
            "Wkg": 1 
        } 
    }
])