2017-02-07 4 views
1

J'ai quelques données, produits et ils ont les valeurs des attributs et les id de cet attribut. Les étiquettes des attributs sont dans la même collection mais avec type: "attribute" au lieu de `type:" product ". J'ai besoin de rejoindre ceux-ci afin que j'ai les produits, y compris l'étiquette des attributs et leurs valeurs.

Je des données très simples de l'échantillon elle: https://gist.github.com/flowl/632243bca8f2907a672f66920ea0f793

Mon agrégation ressemble à ceci:

db.input.aggregate([ 
    { 
     $unwind: "$attributes" 
    }, 
    { 
     $lookup: { 
      from: "input", 
      localField: "attributes.id", 
      foreignField: "attributeId", 
      as: "attributeLabels" 
     } 
    }, 
    { 
     $match: { "output": { $ne: [] } } 
    }, 
    { 
     $group: { 
      _id: "$productId", 
      product: { "$first": "$$CURRENT"} 
     } 
    }, 
    { $group : { _id : "$product._id", data: { $push: "$$ROOT" } } } 
]); 

Le problème est, je veux reformater la sortie de celle-ci:

{ 
    "_id" : ObjectId("5899925339db9185f13432c4"), 
    "data" : [ 
     { 
      "_id" : 111, 
      "product" : { 
       "_id" : ObjectId("5899925339db9185f13432c4"), 
       "type" : "product", 
       "productId" : 111, 
       "attributes" : { 
        "id" : 1, 
        "value" : "L" 
       }, 
       "attributeLabels" : [ 
        { 
         "_id" : ObjectId("5899927539db9185f13432cb"), 
         "type" : "attribute", 
         "attributeId" : 1, 
         "label" : "Size" 
        } 
       ] 
      } 
     } 
    ] 
} 

Pour cela:

{ 
    "_id" : ObjectId("5899925339db9185f13432c4"), 
    "type" : "product", 
    "productId" : 111, 
    "attributes" : [ 
     { 
      "_id" : ObjectId("5899927539db9185f13432cb"), 
      "type" : "attribute", 
      "attributeId" : 1, 
      "label" : "Size", 
      "value" : "L" 
     } 
    ] 
} 
+0

Quelle est votre mongo version db? – Veeram

+0

@Veeram db.version() - 3.4.2 – DanFromGermany

Répondre

1

Vous pouvez utiliser l'agrégation ci-dessous.

Ceci remplacera la valeur du champ id dans le tableau attributes par la valeur $lookUp.

La réponse n'est pas exactement similaire mais elle inclut toutes les valeurs d'attribut de product.

db.input.aggregate([{ 
    $unwind: "$attributes" 
}, { 
    $lookup: { 
     from: "input", 
     localField: "attributes.id", 
     foreignField: "attributeId", 
     as: "attributes.id" 
    } 
}, { 
    $match: { 
     "attributes.id": { 
      $ne: [] 
     } 
    } 
}, { 
    $unwind: "$attributes.id" 
}, { 
    $group: { 
     _id: "$_id", 
     type: { 
      "$first": "$type" 
     }, 
     productId: { 
      "$first": "$productId" 
     }, 
     attributes: { 
      "$push": "$attributes" 
     } 
    } 
}]); 

Exemple de réponse

{ 
    "_id": ObjectId("5899925339db9185f13432c4"), 
    "type": "product", 
    "productId": 111, 
    "attributes": [{ 
     "id": { 
      "_id": ObjectId("5899927539db9185f13432cb"), 
      "type": "attribute", 
      "attributeId": 1, 
      "label": "Size" 
     }, 
     "value": "L" 
    }] 
} 
+0

C'est sympa, mais il y a un problème: le nouveau tableau d'attributs remplace le tableau d'origine au lieu de fusionner. En d'autres termes, le champ 'value' de l'attribut est perdu. – DanFromGermany

+0

Réponse mise à jour. – Veeram

+0

Le premier groupe $ avec '" $ first ":" $$ CURRENT "' fait que mon tableau d'attributs n'a qu'un seul élément au lieu de tout (comme le produit 111 a 2 attributs), comment puis-je résoudre ce problème? – DanFromGermany