2017-03-31 6 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'} 

와 나는 단지 특정 날짜 이전에 생성 된 제목을 너무 집계 할 또는 빈 목록을 반환하면 집계 파이프 라인을 어떻게 구조화 할 수 있습니까?

그래서 원하는 출력은 다음과 같습니다

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

하지만 날짜가 생성 한 데이터를 주조하는 방법을 알아낼 수 없습니다

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

내가 뭔가를 간다 집계 파이프 라인을 가지고 비어있는 필수 시간 이후이므로 빈 제목으로 그룹화됩니다.

+1

당신이 $의 push' 흡수하고 아무것도 추가하지 않습니다'더미 필드 (존재하지 않는 필드)를 사용하여 좋아하는 경우에 비 표준, 당신이 그것을 간단하게 할 수 있지만. {$ {$ lte : [ "$ data.date_created", requested_date}}, "$ data.title {$ {title}}"{{ "$ group": {_id : "$ owner"제목} {$ push : {$ cond : [{ ","$ 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

기준에 맞는 항목이 없을 때 빈 배열을 엄격하게 요구하지 않으면 훨씬 간단 해집니다. 그렇다면 $match$group$push 또는 $addToSet과 같이 사용하면됩니다. 예를 들어

:

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" ] } 

또 다른 옵션은 $filter을 사용하여 $group/$push 첫째, 다음 필터 배열 요소를 수행하는 것 (3.2 이상 MongoDB를 필요). 예를 들어

:

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" } ] }