2017-08-31 2 views
0

Après agrégations i obtenir ce résultat,tableau de projet d'objets à clé Valeur

{ 
    "_id" : { 
     "date" : ISODate("2017-08-30T00:00:00.000Z") 
    }, 
    "aggr" : [ 
     { 
      "gender" : "unknown", 
      "count" : 365 
     }, 
     { 
      "gender" : "male", 
      "count" : 2 
     } 
    ] 
} 

Est-il possible de convertir en dessous le format

{ 
    "date" : ISODate("2017-08-30T00:00:00.000Z"), 
    "unknown" : 365, 
    "male" : 2 
} 

Essayé en utilisant $unwind et $project, mais ne pouvait pas convertir les objets du tableau en paires de valeurs clés

Répondre

1

Oui, en utilisant $arrayToObject et $map pour convertir les exis tableau ting à un format qu'il accepte:

db.collection.aggregate([ 
    { "$replaceRoot": { 
    "newRoot": { 
     "$arrayToObject": { 
     "$concatArrays": [ 
      [{ "k": "date", "v": "$_id.date" }], 
      { "$map": { 
      "input": "$aggr", 
      "in": { "k": "$$this.gender", "v": "$$this.count" } 
      }} 
     ] 
     } 
    }  
    }} 
]) 

Bien sûr, si cela est en fait que sur la « queue » d'une agrégation existante et que vous ne disposez pas d'au moins MongoDB 3.4.4 où l'opérateur est introduit, puis vous pouvez simplement remodeler le résultat dans le code client:

db.collection.aggregate([ 
    // existing pipeline 
]).map(d => 
    Object.assign(
    { date: d._id.date }, 
    d.aggr.reduce((acc,curr) => 
     Object.assign(acc,{ [curr.gender]: curr.count }),{} 
    ) 
) 
) 
+0

C'est ce que @ Steve la réponse dit, et il dit aussi ce qu'il faut faire dans les versions inférieures à la fin du pipeline à la place. Vous ne pouvez pas utiliser une valeur en tant que nom clé directement dans un pipeline d'agrégation dans une version inférieure. –

+0

Ok merci, la réponse a été mise à jour. Will try this – Steve

+0

Je n'écris pas le résultat de l'agrégation à une collection, donc avant 3.4.4 n'est-il pas possible de le faire dans l'agrégation elle-même? – Steve