2017-07-11 5 views
0

ich eine harte Zeit hatte, als versuchte Feldwert mit vielfältigen Schlüssel, in einem Objekt, beispielsweise abzurufen:MongoDB: Abfragewert mit vielfältigen Schlüssel, in einem Objekt

Laufender Befehl:

db.stuff.find() 

geben:

{ 
    "_id":ObjectId("5963e65f948dc563d6375f7b"), 
    "color_map":{ 
     "APPLE":"red", 
     "BANANA":"yellow", 
     "SKY":"blue" 
    }, 
    "type":"APPLE" 
} 
{ 
    "_id":ObjectId("5963e65f948dc563d6375f77"), 
    "color_map":{ 
     "BANANA":"yellow", 
     "PEACH":"pink", 
     "SKY":"blue" 
    }, 
    "type":"PEACH" 
} 

die Frage ist also, wie die Farbergebnisse reinen MongoDB Operatoren zu erhalten (wird mit Aggregat Betreiber bevorzugen), das folgende Ergebnis zu erhalten:

{ 
    "_id":ObjectId("5963e65f948dc563d6375f7b"), 
    "type":"APPLE", 
    "color":"red" 
} 
{ 
    "_id":ObjectId("5963e65f948dc563d6375f77"), 
    "type":"PEACH", 
    "color":"pink" 
} 

Follow-up: Die mongoDB Version ist 3.2.9 und Upgrade auf die neueste Version werden andere Komponenten zum Absturz bringen, so könnten wir es implementieren, ohne $ objectToArray mit (neu in 3.4.4)?

+0

Scheint, wie Art eine seltsame Art und Weise diese Informationen zu speichern. Sind Sie sicher, dass dies der beste Weg für Ihre Bedürfnisse ist? –

Antwort

0

Sie können $objectToArray verwenden, um color_map Embedded Doc in Array von Schlüsselwert (k v) Paare in 3.4.4 Version zu konvertieren.

$indexOfArray Bedienungsperson den passenden Index im type'scolor_map von $arrayElemAt gefolgt zu finden, das Element bei gefunden Index und Projizieren der Wert des Elements in color Feld abzurufen.

$let um die colorkvs Variable und Referenz innerhalb in Ausdruck zu erstellen.

So etwas wie unten

db.collectionname.aggregate([ 
    { 
     "$project": { 
     "color": { 
      "$let": { 
      "vars": { 
       "colorkvs": { 
       "$objectToArray": "$color_map" 
       } 
      }, 
      "in": { 
       "$let": { 
       "vars": { 
        "colorkv": { 
        "$arrayElemAt": [ 
         "$$colorkvs", 
         { 
         "$indexOfArray": [ 
          "$$colorkvs.k", 
          "$type" 
         ] 
         } 
        ] 
        } 
       }, 
       "in": "$$colorkv.v" 
       } 
      } 
      } 
     }, 
     "type":1 
     } 
    } 
]) 

Sie die Pipeline verkürzen können die äußeren $let Ausdruck durch Entfernen.

db.collectionname.aggregate([ 
    { 
    "$project": { 
     "color": { 
     "$let": { 
      "vars": { 
      "colorkv": { 
       "$arrayElemAt": [ 
       { 
        "$objectToArray": "$color_map" 
       }, 
       { 
        "$indexOfArray": [ 
        { 
         "$objectToArray": "$color_map" 
        }, 
        "$type" 
        ] 
       } 
       ] 
      } 
      }, 
      "in": "$$colorkv.v" 
     } 
     }, 
     "type": 1 
    } 
    } 
]) 

JS Lösung für niedrigere Versionen

db.collectionname.find({}).map(doc => ({ 
    "_id": doc._id, 
    "type": doc.type, 
    "color": doc.color_map[Object.keys(doc.color_map).find(k => k === doc.type)] 
})); 
Verwandte Themen