2015-05-18 80 views
1

这里的文件一个例子,我用:

{ 
    "_id" : ObjectId("554a1f5fe36a768b362ea5c0"), 
    "store_state" : 1, 
    "services" : [ 
     { 
      "id" : "XXX", 
      "state" : 1, 
      "active": true 
     }, 
     { 
      "id" : "YYY", 
      "state" : 1, 
      "active": true 
     }, 
     ... 
    ] 
} 

我要输出与“Y”一个新的领域,如果id为“XXX”和积极的真实,“N “在任何其他情况下。每个文档都没有“XXX”作为标识的服务元素(在这种情况下,输出“N”)。

这里是我的时刻查询:

db.stores.aggregate({ 
    $match : {"store_state":1} 
}, 
{ $project : { 
    "XXX_active": { 
     $cond: [ { 
      $and:[ 
       {$eq:["services.$id","XXX"]}, 
       {$eq:["services.$active",true]} 
      ]},"Y","N" 
     ] } 
    } 
}).pretty() 

但它总是输出"N""XXX_active"领域。

预期输出我需要的是:

{ 
    "_id" : ObjectId("554a1f5de36a768b362e7e6f"), 
    "XXX_active" : "Y" 
}, 
{ 
    "_id" : ObjectId("554a1f5ee36a768b362e9d25"), 
    "XXX_active" : "N" 
}, 
{ 
    "_id" : ObjectId("554a1f5de36a768b362e73a5"), 
    "XXX_active" : "Y" 
} 

的可能结果的其它例子:

{ 
    "_id" : ObjectId("554a1f5de36a768b362e7e6f"), 
    "XXX_active" : "Y", 
    "YYY_active" : "N" 
}, 
{ 
    "_id" : ObjectId("554a1f5ee36a768b362e9d25"), 
    "XXX_active" : "N", 
    "YYY_active" : "N" 
}, 
{ 
    "_id" : ObjectId("554a1f5de36a768b362e73a5"), 
    "XXX_active" : "Y", 
    "YYY_active" : "Y" 
} 

只有一个每个对象XXX_active并没有重复对象,但我需要一个XXX_active即使所有对象服务id元素“XXX”不存在。有人可以帮忙吗?

+0

您能告诉我们预期的产量吗? – chridam

+0

我需要的输出是: {“_id”:ObjectId(“554a1f5de36a768b362e7e6f”),“XXX_active”:“Y”} {“_id”:ObjectId(“554a1f5ee36a768b362e9d25”),“XXX_active”:“N”} { “_id”:ObjectId(“554a1f5de36a768b362e73a5”),“XXX_active”:“Y”} 每个对象只有一个XXX_active。谢谢 –

回答

0

首先$unwindservices数组,然后如下面使用$cond

db.stores.aggregate({ 
    "$match": { 
     "store_state": 1 
    } 
}, { 
    "$unwind": "$services" 
}, { 
    "$project": { 
     "XXX_active": { 
      "$cond": [{ 
       "$and": [{ 
        "$eq": ["$services.id", "XXX"] 
       }, { 
        "$eq": ["$services.active", true] 
       }] 
      }, "Y", "N"] 
     } 
    } 
},{"$group":{"_id":"$_id","XXX_active":{"$first":"$XXX_active"}}}) //group by id 
+0

感谢您的回应,它的工作原理并不完全符合我的要求。 如果我只需要一个结果“XXX_active”与Y或N(因为总是有一个服务XXX),是否需要分组? 使用您的解决方案,查询将检查每个服务的XXX/true并输出每个服务权限的结果? 我需要的输出是: { “_id”:的ObjectId( “554a1f5de36a768b362e7e6f”), “XXX_active”: “Y”} { “_id”:的ObjectId( “554a1f5ee36a768b362e9d25”), “XXX_active”: “N” } {“_id”:ObjectId(“554a1f5de36a768b362e73a5”),“XXX_active”:“Y”} 只有一个XXX_active每个对象。 谢谢, –

+0

@JulienF检查编辑答案 – Yogesh

+0

谢谢,如果我看看$组,你拿第一个XXX_active,但服务XXX并不总是在服务数组中的第一个位置,使用这种解决方案,我们可以采取XXX_Active检查YYY服务是否正确? –

0

以下聚合管线将给出所需的结果。您需要首先将$unwind运算符应用于services阵列字段,作为您的初始聚合管道步骤。这将从输入文档中解构services数组字段以输出每个元素的文档。每个输出文档用一个元素值替换数组。

db.stores.aggregate([ 
    { 
     "$match" : {"store_state": 1} 
    }, 
    { 
     "$unwind": "$services" 
    }, 
    { 
     "$project": { 
      "store_state" : 1, 
      "services": 1, 
      "XXX_active": { 
       "$cond": [ 
        { 
         "$and": [ 
          {"$eq":["$services.id", "XXX"]}, 
          {"$eq":["$services.active",true]} 
         ] 
        },"Y","N" 
       ] 
      } 
     } 
    }, 
    { 
     "$match": { 
      "services.id": "XXX" 
     } 
    }, 
    { 
     "$group": { 
      "_id": { 
       "_id": "$_id", 
       "store_state": "$store_state", 
       "XXX_active": "$XXX_active" 
      }, 
      "services": { 
       "$push": "$services" 
      } 
     } 
    }, 
    { 
     "$project": { 
      "_id": "$_id._id", 
      "store_state" : "$_id.store_state", 
      "services": 1, 
      "XXX_active": "$_id.XXX_active" 
     } 
    } 
]) 
+1

谢谢,它的作品!它减慢了查询速度,但结果正常。 –

+0

考虑在'store_state'字段中添加一个索引,但首先要确认'find({“store_state”:1})是否正在使用索引,可能是''store_state_1''',您可以发布'.explain() ?否则,你的聚合管道应该使用与find()相同的查询计划。 – chridam

+0

我刚才看到你的解决方案不太好。 如果XXX存在且处于活动状态,则会输出相同的ID两次,其中一个在XXX_active处为“Y”。但其他服务的另一个ID为“N”。 –