2017-11-23 3 views
0

Ich hatte ein Problem mit Mongodb-Aggregation mit mehr als 2 Sammlungen. Hier repräsentiere ich meine Kollektionen.
First Collection: PotentialMongodb Aggregation mit separaten Sammlungen

{ 
"_id" : ObjectId("5a0d1cb1d2fffa95ed85b3ba"), 
"potential_id" : "P-00", 
"potential_name" : "NKCL"} 

Meine zweite Kollektion: Büro

{ 
"_id" : ObjectId("5a0d20e8d2fffa95ed85b5bc"), 
"potential_id" : "P-00", 
"potential_name" : "NKCL", 
"revision_id" : "R0", 
"office_name" : "Marketing office", 
"vertical_info" : [ 
    { 
     "vertical_name" : "MEP", 
     "estimated_team" : "Marketing" 
    }, 
    { 
     "vertical_name" : "BIM", 
     "estimated_team" : "Marketing" 
    }, 
    { 
     "vertical_name" : "V1", 
     "estimated_team" : "Marketing" 
    } 
]} 

Meine dritte Sammlung: Dienstleistungen

{ 
"_id" : ObjectId("5a0d212cd2fffa95ed85b5e6"), 
"potential_id" : "P-00", 
"potential_name" : "NKCL", 
"revision_id" : "R0", 
"office_name" : "Marketing office", 
"vertical_name" : "MEP", 
"service_info" : [ 
    { 
     "service_name" : "Service 1", 
     "total_cost" : 1 
    }, 
    { 
     "service_name" : "Service 2", 
     "total_cost" : 2 
    } 
]} 

Meine vierte Kollektion: servicebuild

{ 
"_id" : ObjectId("5a0d2175d2fffa95ed85b612"), 
"potential_id" : "P-00", 
"potential_name" : "NKCL", 
"revision_id" : "R0", 
"office_name" : "Marketing office", 
"vertical_name" : "MEP", 
"service_name" : "Service 1", 
"service_building_info" : [ 
    { 
     "building_no" : 1, 
     "building_name" : "Building 1" 
    }, 
    { 
     "building_no" : 2, 
     "building_name" : "Building 2" 
    }, 
    { 
     "building_no" : 3, 
     "building_name" : "Building 3" 
    } 
]} 

Jetzt möchte ich die oben genannten 4 Sammlungen mit in einer einzigen Aggregation Anfrage verbinden. Ich sah die meisten Beispiele, um nur den beiden Sammlungen beizutreten.

Mein Ausgang aussieht wie dieser

{ 
    "_id" : ObjectId("5a0d1cb1d2fffa95ed85b3ba"), 
"potential_id" : "P-00", 
"potential_name" : "NKCL" 
"revision_id" : "R0", 
"office_name" : "Marketing office", 
"vertical_info" : [ 
{ 
    "vertical_name" : "MEP", 
    "estimated_team" : "Marketing" 
    "service_info" : [ 
     { 
      "service_name" : "Service 1", 
      "total_cost" : 1 
      "service_building_info" : [ 
       { 
        "building_no" : 1, 
        "building_name" : "Building 1" 
       }, 
       { 
        "building_no" : 2, 
        "building_name" : "Building 2" 
       }, 
       { 
        "building_no" : 3, 
        "building_name" : "Building 3" 
       } 
      ] 
     }, 
     { 
      "service_name" : "Service 2", 
      "total_cost" : 2 
     } 
    ] 
}, 
{ 
    "vertical_name" : "BIM", 
    "estimated_team" : "Marketing" 
}, 
{ 
    "vertical_name" : "V1", 
    "estimated_team" : "Marketing" 
}]} 

Jeder kann helfen, mein Problem zu lösen.

+2

MongoDB ist eine NoSQL-Datenbank. Es ist nicht wie RDBMS, wo Sie mehr normalisierte Daten haben werden. Hier in NoSQL können Sie Duplikate der Datensätze/Dokumente haben (da wir sie in jedes Dokument einbetten werden, z. B. die Sammlung "Potential" in "Büro" oder auf irgendeine Weise einbetten, je nachdem, welches Szenario am besten passt). Ich würde Ihnen empfehlen, Ihre Sammlungen so umzugestalten, dass sie nur eine minimale Anzahl von Sammlungen haben, um das beste Ergebnis der NoSQL-Datenbank zu erhalten. –

Antwort

0

Hier ist die Aggregation, die gewünschten Ausgabeergebnisse:

db.potential.aggregate([{ 
    $lookup: { 
     from: 'office', 
     localField: 'potential-id', 
     foreignField: 'potential-id', 
     as: 'office' 
    } 
    }, 
    { 
    $unwind: '$office' 
    }, 
    { 
    $project: { 
     potential_id: 1, 
     potential_name: 1, 
     revision_id: '$office.revision_id', 
     office_name: '$office.office_name', 
     vertical_info: '$office.vertical_info' 
    } 
    }, 
    { 
    $lookup: { 
     from: 'services', 
     localField: 'vertical_info.vertical_name', 
     foreignField: 'vertical_name', 
     as: 'services' 
    } 
    }, 
    { 
    $project: { 
     potential_id: 1, 
     potential_name: 1, 
     revision_id: 1, 
     office_name: 1, 
     vertical_info: { 
     $map: { 
      input: '$vertical_info', 
      as: 'vertical_info_item', 
      in: { 
      vertical_name: '$$vertical_info_item.vertical_name', 
      estimated_team: '$$vertical_info_item.estimated_team', 
      service_info: { 
       $filter: { 
       input: '$services', 
       as: 'service', 
       cond: { 
        $eq: ['$$vertical_info_item.vertical_name', '$$service.vertical_name'] 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    }, 
    { 
    $project: { 
     potential_id: 1, 
     potential_name: 1, 
     revision_id: 1, 
     office_name: 1, 
     vertical_info: { 
     $map: { 
      input: '$vertical_info', 
      as: 'vertical_info_item', 
      in: { 
      vertical_name: '$$vertical_info_item.vertical_name', 
      estimated_team: '$$vertical_info_item.estimated_team', 
      service_info: { 
       $arrayElemAt: ['$$vertical_info_item.service_info.service_info', 0] 
      } 
      } 
     } 
     } 
    } 
    }, 
    { 
    $lookup: { 
     from: 'servicebuild', 
     localField: 'vertical_info.service_info.service_name', 
     foreignField: 'service_name', 
     as: 'servicebuild' 
    } 
    }, 
    { 
    $project: { 
     potential_id: 1, 
     potential_name: 1, 
     revision_id: 1, 
     office_name: 1, 
     vertical_info: { 
     $map: { 
      input: '$vertical_info', 
      as: 'vertical_info_item', 
      in: { 
      vertical_name: '$$vertical_info_item.vertical_name', 
      estimated_team: '$$vertical_info_item.estimated_team', 
      service_info: { 
       $map: { 
       input: '$$vertical_info_item.service_info', 
       as: 'service_info_item', 
       in: { 
        service_name: '$$service_info_item.service_name', 
        total_cost: '$$service_info_item.total_cost', 
        service_building_info: { 
        $filter: { 
         input: '$servicebuild', 
         as: 'servicebuild_item', 
         cond: { 
         $eq: ['$$service_info_item.service_name', '$$servicebuild_item.service_name'] 
         } 
        } 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    }, 
    { 
    $project: { 
     potential_id: 1, 
     potential_name: 1, 
     revision_id: 1, 
     office_name: 1, 
     vertical_info: { 
     $map: { 
      input: '$vertical_info', 
      as: 'vertical_info_item', 
      in: { 
      $cond: { 
       if: { 
       $ne: ['$$vertical_info_item.service_info', null] 
       }, 
       then: { 
       vertical_name: '$$vertical_info_item.vertical_name', 
       estimated_team: '$$vertical_info_item.estimated_team', 
       service_info: { 
        $map: { 
        input: '$$vertical_info_item.service_info', 
        as: 'service_info_item', 
        in: { 
         service_name: '$$service_info_item.service_name', 
         total_cost: '$$service_info_item.total_cost', 
         service_building_info: { 
         $filter: { 
          input: '$$service_info_item.service_building_info', 
          as: 'servicebuild_item', 
          cond: { 
          $eq: ['$$service_info_item.service_name', '$$servicebuild_item.service_name'] 
          } 
         } 
         } 
        } 
        } 
       } 
       }, 
       else: { 
       vertical_name: '$$vertical_info_item.vertical_name', 
       estimated_team: '$$vertical_info_item.estimated_team' 
       } 
      } 
      } 
     } 
     } 
    } 
    }, 
    { 
    $project: { 
     potential_id: 1, 
     potential_name: 1, 
     revision_id: 1, 
     office_name: 1, 
     vertical_info: { 
     $map: { 
      input: '$vertical_info', 
      as: 'vertical_info_item', 
      in: { 
      $cond: { 
       if: { 
       $ne: ['$$vertical_info_item.service_info', undefined] 
       }, 
       then: { 
       vertical_name: '$$vertical_info_item.vertical_name', 
       estimated_team: '$$vertical_info_item.estimated_team', 
       service_info: { 
        $map: { 
        input: '$$vertical_info_item.service_info', 
        as: 'service_info_item', 
        in: { 
         service_name: '$$service_info_item.service_name', 
         total_cost: '$$service_info_item.total_cost', 
         service_building_info: { 
         $arrayElemAt: ['$$service_info_item.service_building_info.service_building_info', 0] 
         } 
        } 
        } 
       } 
       }, 
       else: { 
       vertical_name: '$$vertical_info_item.vertical_name', 
       estimated_team: '$$vertical_info_item.estimated_team' 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
])