2015-06-16 76 views
0

我想要使用聚合來獲取此數組僅與那些在2015-06-16之後具有開始字段的故障單。有人可以幫助我的管道?獲取mongodb數組中的匹配元素

{ 
    "name" : "array", 
    "tickets" : [ 
     { 
      "id" : 1, 
      "sort" : true, 
      "start" : ISODate("2015-06-15T22:00:00.000Z") 
     }, 
     { 
      "id" : 2, 
      "sort" : true, 
      "start" : ISODate("2015-06-16T22:00:00.000Z") 
     }, 
     { 
      "id" : 3, 
      "sort" : true, 
      "start" : ISODate("2015-06-17T22:00:00.000Z") 
     } 
    ] 
} 
+0

[MongoDB Aggregate $ unwind $ match using date:我錯過了什麼?](http://stackoverflow.com/questions/13563002/mongodb-aggregate-unwind-match-using-date-what-did -我錯過了) – Yogesh

回答

1

這是真的,可用於MongoDB的方法「標準投影」操作,如.find()將最多隻從陣列返回一個「單一的匹配元素」即通過「查詢」部分中的positional $ operator表單或「投影」部分中的$elemMatch查詢。

爲了做這種「遠程」的操作,你需要擁有更大的「操作」和「過濾」對數組能力aggregation framework

collection.aggregate(
    array( 
     # First match the "document" to reduce the pipeline 
     array(
      '$match' => array(
       array( 
        'tickets.start' => array(
         '$gte' => new MongoDate(strtotime('2015-06-16 00:00:00')) 
        ) 
       ) 
      ) 
     ), 

     # Then unwind the array 
     array('$unwind' => '$tickets'), 

     # Match again on the "unwound" elements to filter 
     array(
      '$match' => array(
       array( 
        'tickets.start' => array(
         '$gte' => new MongoDate(strtotime('2015-06-16 00:00:00')) 
        ) 
       ) 
      ) 
     ), 

     # Group back to original structure per document 
     array(
      '$group' => array( 
        '_id' => '$_id', 
        'name' => array('$first' => '$name'), 
        'tickets' => array(
         '$push' => '$tickets' 
       ) 
      ) 
     )   
    ) 
) 

或者你所能使用$redact運營商與MongoDB的2.6或更大,其基本上使用$cond運算符的語法,因爲它的輸入簡化:

collection.aggregate(
    array( 
     # First match the "document" to reduce the pipeline 
     array(
      '$match' => array(
       array( 
        'tickets.start' => array(
         '$gte' => new MongoDate(strtotime('2015-06-16 00:00:00')) 
        ) 
       ) 
      ) 
     ), 

     # Redact entries from the array 
     array(
      '$redact' => array(
       'if' => array(
        '$gte' => array(
         array('$ifNull' => array(
          '$start', 
          new MongoDate(strtotime('2015-06-16 00:00:00')) 
         )), 
         new MongoDate(strtotime('2015-06-16 00:00:00:00')) 
        ) 
       ), 
       'then' => '$$DESCEND', 
       'else' => '$$PRUNE' 
      ) 
     ) 
    ) 
) 

所以例子做了「相同薄g「中」過濾「數組中的」不符合指定條件並返回「多於一個」元素的元素,這是基本投影無法做到的。

0

您應該使用Aggregation來獲得輸出。

應使用以下查詢:

db.collection.aggregate({ 
    $match: { 
    name: "array" 
    } 
}, { 
    $unwind: "$tickets" 
}, { 
    $match: { 
    "tickets.start": { 
     $gt: ISODate("2015-06-16") 
    } 
    } 
}, { 
    $group: { 
    "_id": "name", 
    "tickets": { 
     $push: "$tickets" 
    } 
    } 
})