2017-10-14 10 views
0

Je suis coincé sur quelque chose et j'ai besoin de votre aide. Je veux effectuer une requête agrégée mongo sur la collection ci-dessous afin que je puisse obtenir le poids total comme somme de Max de chaque liste de sous-réseau de boxWeight1 et boxWeight2, à savoir, sum+=max[boxWeight1,boxWeight2] for each array item in boxList array et d'autres champs doivent être projetés tel quel mais avec des clés différentes Des noms.En Somme Mongo pour chaque élément de tableau après avoir trouvé Max de chaque

Collection est un peu comme ça ...

{ 
    _id: '', 
    email: '[email protected]', 
    number: 12345, 
    boxDetail: { 
     boxname: 'package_yugal', 
     boxList: [ 
      { 
       boxWeight1: '4.0', //this is max here. so it will be added 
       boxWeight2: '2.0' 
      }. 
      { 
       boxWeight1: '4.0', 
       boxWeight2: '8.0'  //this is max here. so it will be added 
      } 
      { 
       boxWeight1: '0.0', 
       boxWeight2: '2.0'  //this is max here. so it will be added 
      } 
     ] 
    } 
} 

Ainsi, le résultat de la collection ci-dessus après avoir effectué la requête doit être un peu comme ceci:

{ 
    'User Mail': '[email protected]', 
    'Order Number': '12345', 
    'Total Weight': '14.0' // 4 + 8 + 2 
} 

J'espère que vous avez compris ma question . Merci d'avance.

Répondre

0

Pouvez-vous s'il vous plaît essayer la requête ci-dessous:

db.collection.aggregate([ 
      { 
       $unwind : "$boxList" 
      }, 
      { 
       $project : { 
          "email" : 1, 
          "number" : 1, 
          "maxWeight" : { $cond : { if : { $gt : 
           ["$boxList.boxWeight1","$boxList.boxWeight2"]} , 
                then : "$boxList.boxWeight1" , 
                else : "$boxList.boxWeight2"} 
             } 
         } 
      }, 
      { 
       $group : { 
          _id : "$_id" , 
          Total : { $sum : "$maxWeight" }, 
          email : { $first : "$email" }, 
          number : {$first : "$number"} 
         } 
      }, 
      { 
       $project : { 
          "User Mail" : "$email" , 
          "Order Number" : "$number", 
          "Total Weight" : "$Total", 
          _id : 0 
          } 
      } 
    ]); 
+0

Oui, j'ai essayé un peu comme cela ne. J'ai posté ma réponse ci-dessus. Merci d'avoir répondu. Maintenant, je suis sûr que ma requête est dans la bonne direction. –

0

Eh bien cela a fonctionné ...

db.collection.aggregate([ 
{ 
    $project: { 
     email: '$email', 
     number: '$number', 
     boxList: '$boxDetail.boxList' 
    }, 
    { $unwind: '$boxList' }, 
    { 
     $group: { 
      _id: '$_id', 
      'Total Weight': { 
       $sum:{ 
         $max:['$boxdetail.BoxActualWeight', '$boxdetail.BoxDimWeight'] 
        } 
       }, 
       'User Email': { 
       $first: '$email' 
       }, 
       'Order Number':{ 
       $first: '$number' 
       } 
     } 

    } 
}]) 

Cela donne le résultat avec la colonne _id avec elle. Ce qui peut être supprimé avec une autre projection après.

0

Vous pouvez utiliser une combinaison d'opérateurs pour atteindre la version 3.4 la plus récente.

La liste ci-dessous résume la liste des éléments max.

$objectToArray + $max de convertir en vue de tableau (tableau de paires k et v) et pick max pour chaque élément.

$map pour afficher la liste des valeurs maximales suivies de $sum pour additionner les valeurs maximales.

Quelque chose comme

{ 
    "$addFields": { 
    "Total_Weight": { 
     "$sum": { 
     "$map": { 
      "input": "$boxList", 
      "in": { 
      "$let": { 
       "vars": { 
       "weigh": { 
        "$objectToArray": "$$this" 
       } 
       }, 
       "in": { 
       "$max": "$$weight.v" 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

Vous pouvez simplifier au-dessous si vous avez juste deux attributs.

{ 
    "$addFields": { 
    "Total_Weight": { 
     "$sum": { 
     "$map": { 
      "input": "$boxList", 
      "as": "result", 
      "in": { 
      "$max": [ 
       "$$result.boxWeight1", 
       "$$result.boxWeight2" 
      ] 
      } 
     } 
     } 
    } 
    } 
}