2017-03-31 55 views
0

如果我有文件,我聚集,我想一個子領域,如:MongoDB的管道匯聚管道替換值

{data: {'date_created': '2011-01-01', 'title': 'abc'}, 'owner': 'Jim'} 
{data: {'date_created': '2011-05-01', 'title': 'def'}, 'owner': 'Bob'} 
{data: {'date_created': '2011-03-01', 'title': 'ghi'}, 'owner': 'Jim'} 
{data: {'date_created': '2011-03-01', 'title': ''}, 'owner': 'Sam'} 

,我想聚集,這樣我只需要在某個日期之前創建的標題或返回一個空的列表,我將如何構造聚合管道?

因此所需的輸出將是:

{owner: "Jim", titles: ["abc", "def"], 
owner: "Bob", titles: [], 
owner: "Sam", titles: []} 

我有一個總的管道是去是這樣的:

lookup => unwind => 
     {'$match': 
      {'$or': [{'data.date_created': {'$lte': requested_date}}, {'data.title': {'$exists': False}}]}}} 

,但我無法弄清楚如何投其中的日期創建的數據在需要的時間之後是空白的,所以它將被分組爲空白標題。

+1

雖然不標準,你可以,如果你使用虛擬場(不存在的領域)的'$ push'會吸收,也不會增加任何類似簡化它。 '{「$ group」:{ _id:「$ owner」,標題:{ $ push:{$ cond:[{$ lte:[「$ data.date_created」,requested_date]},「$ data.title 「,」$ nonexist「 ] } } } }'' – Veeram

回答

1

希望這有助於。您可以根據日期進行有條件的推送,然後過濾出titles數組中的空白項目。

db.collection.aggregate([ 
    {"$group":{ 
    _id:"$owner",titles:{ 
     $push: { $cond:[ 
     { $lte: [ "$data.date_created", "2011-03-01" ]},"$data.title","" 
      ] 
     } 
     } 
    } 
    }, 
    { 
    $project: { 
     _id:0, 
     owner : "$_id", 
     titles: { 
     $filter: { 
      input: "$titles", 
      as: "titles", 
      cond: { $ne: [ "$$titles", "" ] } 
     } 
     } 
    } 
    } 
]) 

結果:

{ "titles" : [ ], "owner" : "Bob" } 
{ "titles" : [ "abc", "ghi" ], "owner" : "Jim" } 
{ "titles" : [ ], "owner" : "Sam" } 
1

如果您沒有嚴格要求空數組,當沒有符合條件的項目時,這會使其更加簡單。如果是這種情況,您可以簡單地使用$push$addToSet執行$match$group

例如:

db.foo.aggregate([ 
    { $match : {'data.date_created': {'$lte': "2011-03-01"}}}, 
    { $group: { 
     _id: "$owner", 
     titles : {$push : "$data.title"} 
    }} 
]) 

結果:

{ "_id" : "Sam", "titles" : [ "" ] } 
{ "_id" : "Jim", "titles" : [ "abc", "ghi" ] } 

另一種選擇是做你$group/$push第一,然後過濾該陣列使用$filter元件(需要的MongoDB 3.2+)。

例如:

db.foo.aggregate([ 
    { $group: { 
     _id: "$owner", 
     data : {$push : "$data"} 
    }}, 
    { 
     $project: { 
     titles: { 
      $filter: { 
       input: "$data", 
       as: "item", 
       cond: { $lte: [ "$$item.date_created", "2011-03-01" ] } 
      } 
     } 
    }} 
]) 

結果:

{ "_id" : "Sam", "titles" : [ { "date_created" : "2011-03-01", "title" : "" } ] } 
{ "_id" : "Bob", "titles" : [ ] } 
{ "_id" : "Jim", "titles" : [ { "date_created" : "2011-01-01", "title" : "abc" }, { "date_created" : "2011-03-01", "title" : "ghi" } ] }