2017-09-08 5 views
2

Je fais l'agrégation MongoDB. Je veux rechercher deux collections puis projeter seulement le champ désiré dans le tableau imbriqué.Projet d'agrégation Mongodb après recherche

Deux collections Lookup:

db.pitcher.find() assez()

{ 
     "_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() assez()

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

Aggr requête 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() 

sortie Enfin souhaitée:

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

Je veux nom et gameRecord qui contient gameIndex (dans ce cas) 1 uniquement.

Veuillez améliorer ma requête agrégée. Nombreux tnx pour le code Spring si vous en avez un.

Répondre

1

Vous pouvez utiliser la requête suivante dans 3.4.

La requête ci-dessous utilise $addFields pour remplacer le awayPitcherList existant avec le awayPitcherList mis à jour qui comprend name et gameRecord.

$map stade pour maintenir le champ name et $filter pour filtrer les gameRecord pour retenir correspondant seul élément gameIndex.

Agrégation similaire pour 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 
        ] 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
]) 

utilisation ci-dessous requête globale pour 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

Merci beaucoup –

+0

Puis-je aussi avoir la requête $ de projet? J'ai du mal à trouver le constructeur de addFields. Tnx –

+0

Np. J'ai ajouté une mise à jour pour 3.2. Veuillez vérifier. – Veeram