2017-09-08 15 views
2

MongoDB 집계를하고 있습니다. 두 개의 컬렉션을 검색 한 다음 원하는 필드 만 중첩 된 배열에 투영하려고합니다.조회 후 몽고 집합 프로젝트

두 컬렉션을 조회합니다 :

db.pitcher.find()을 꽤()

{ 
     "_id" : ObjectId("59b22eeef224252e6c7eeaf6"), 
     "userId" : "a0", 
     "name" : "test50000", 
     "index" : 50000, 
     "position" : "SP", 
     "order" : 0, 
     "gameRecord" : [ 
       { 
         "seasonIndex" : 2017251, 
         "gameIndex" : 1, 
         "ERA" : 3.00, 
       }, 
     { 
         "seasonIndex" : 2017251, 
         "gameIndex" : 2, 
         "ERA" : 4.50, 
       } 
     ] 
     } 

db.gameResult.find() 꽤()

..
{ 
     "_id" : ObjectId("59b22b7dac48252e6c7eeaf6"), 
     "seasonIndex" : 2017251, 
     "gameIndex" : 1, 
     "away" : "a9", 
     "home" : "a0", 
     "awayScore" : 9, 
     "homeScore" : 4, 
     "awayPitcherList" : [ 
       50180 
     ], 
     "homePitcherList" : [ 
       50000, 
       50049, 
       50048, 
       50047 
     ] 
     } 

ggr eGate에서는 쿼리

> db.gameResult.aggregate([ 
{ 
    $match : {gameIndex : 1 ,home : "a0"} 
}, 
{ 
    $lookup: 
     { 
     from: "pitcher", 
     localField : "awayPitcherList", 
     foreignField : "index", 
     as: "awayPitcherList" 
     } 
}, 
{ 
    $lookup: 
     { 
     from: "pitcher", 
     localField : "homePitcherList", 
     foreignField : "index", 
     as: "homePitcherList" 
     } 
} 
]).pretty() 

마지막으로 원하는 출력 :

"_id" : ObjectId("59b22b7dac48252e6c7eeaf6"), 
"seasonIndex" : 2017251, 
"gameIndex" : 1, 
"away" : "a9", 
"home" : "a0", 
"awayScore" : 9, 
"homeScore" : 4, 

"awayPitcherList" : [ 
    { 
    "name" : "test50180", 
    "gameRecord" : [ 
     { 
       "seasonIndex" : 2017251, 
       "gameIndex" : 1, 
       "ERA" : 3.00, 
     } 
] 
], 
"homePitcherList" : [ 
      { 
    "name" : "test50000", 
    "gameRecord" : [ 
     { 
       "seasonIndex" : 2017251, 
       "gameIndex" : 1, 
       "ERA" : 3.00, 
     } 
], 
      { 
    "name" : "test50049", 
    "gameRecord" : [ 
     { 
       "seasonIndex" : 2017251, 
       "gameIndex" : 1, 
       "ERA" : 3.00, 
     } 
], 
      { 
    "name" : "test50048", 
    "gameRecord" : [ 
     { 
       "seasonIndex" : 2017251, 
       "gameIndex" : 1, 
       "ERA" : 3.00, 
     } 
], 
      { 
    "name" : "test50047", 
    "gameRecord" : [ 
     { 
       "seasonIndex" : 2017251, 
       "gameIndex" : 1, 
       "ERA" : 3.00, 
     } 
] 
] 

내가 (이 경우)의 gameIndex이 포함되어 이름과 gameRecord을 원하는 1 만.

제 집계 쿼리를 개선하십시오. 스프링 코드가있는 경우 많은 tnx가 있습니다.

답변

1

3.4에서 다음 쿼리를 사용할 수 있습니다.

아래 쿼리 namegameRecord 포함 awayPitcherList 갱신하여 기존 awayPitcherList 덮어 $addFields를 이용한다.

$mapname 필드를 유지하는 단계와 $filtergameRecordgameIndex 소자 일치 유지 필터링한다.

homePitcherList에 대한 유사한 집계.

db.gameResult.aggregate(
[ 
    { 
    "$match": { 
     "gameIndex": 1, 
     "home": "a0" 
    } 
    }, 
    { 
    "$lookup": { 
     "from": "pitcher", 
     "localField": "awayPitcherList", 
     "foreignField": "index", 
     "as": "awayPitcherList" 
    } 
    }, 
    { 
    "$addFields": { 
     "awayPitcherList": { 
     "$map": { 
      "input": "$awayPitcherList", 
      "as": "awayPitcher", 
      "in": { 
      "name": "$$awayPitcher.name", 
      "gameRecord": { 
       "$filter": { 
       "input": "$$awayPitcher.gameRecord", 
       "as": "gameRecord", 
       "cond": { 
        "$eq": [ 
        "$$gameRecord.gameIndex", 
        1 
        ] 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    }, 
    { 
    "$lookup": { 
     "from": "pitcher", 
     "localField": "homePitcherList", 
     "foreignField": "index", 
     "as": "homePitcherList" 
    } 
    }, 
    { 
    "$addFields": { 
     "homePitcherList": { 
     "$map": { 
      "input": "$homePitcherList", 
      "as": "homePitcher", 
      "in": { 
      "name": "$$homePitcher.name", 
      "gameRecord": { 
       "$filter": { 
       "input": "$$homePitcher.gameRecord", 
       "as": "gameRecord", 
       "cond": { 
        "$eq": [ 
        "$$gameRecord.gameIndex", 
        1 
        ] 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
]) 

아래의 3.2에 대한 집계 쿼리를 사용하십시오.

db.gameResult.aggregate(
    [ 
     { 
     "$match": { 
      "gameIndex": 1, 
      "home": "a0" 
     } 
     }, 
     { 
     "$lookup": { 
      "from": "pitcher", 
      "localField": "awayPitcherList", 
      "foreignField": "index", 
      "as": "awayPitcherList" 
     } 
     }, 
     { 
     "$project": { 
      "homePitcherList":1, 
      "awayPitcherList": { 
      "$map": { 
       "input": "$awayPitcherList", 
       "as": "awayPitcher", 
       "in": { 
       "name": "$$awayPitcher.name", 
       "gameRecord": { 
        "$filter": { 
        "input": "$$awayPitcher.gameRecord", 
        "as": "gameRecord", 
        "cond": { 
         "$eq": [ 
         "$$gameRecord.gameIndex", 
         1 
         ] 
        } 
        } 
       } 
       } 
      } 
      } 
     } 
     }, 
     { 
     "$lookup": { 
      "from": "pitcher", 
      "localField": "homePitcherList", 
      "foreignField": "index", 
      "as": "homePitcherList" 
     } 
     }, 
     { 
     "$project": { 
      "awayPitcherList":1, 
      "homePitcherList": { 
      "$map": { 
       "input": "$homePitcherList", 
       "as": "homePitcher", 
       "in": { 
       "name": "$$homePitcher.name", 
       "gameRecord": { 
        "$filter": { 
        "input": "$$homePitcher.gameRecord", 
        "as": "gameRecord", 
        "cond": { 
         "$eq": [ 
         "$$gameRecord.gameIndex", 
         1 
         ] 
        } 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    ]) 
+0

너무 감사합니다. –

+0

$ 프로젝트 쿼리도 사용할 수 있습니까? addFields 빌더를 찾는 데 어려움을 겪고 있습니다. Tnx –

+0

Np. 3.2에 대한 업데이트가 추가되었습니다. 확인 부탁합니다. – Veeram