2016-07-06 14 views
4

Ich schreibe ein Python-Skript, das diese Aufgaben:Projekt verschiedene eingebettete Strukturen gleichen Namen

  • Abfrage eine MongoDB Sammlung mit embeded Dokumente
  • Aggregate und Projekt die Feldnamen zu ändern, die in der zurückgeführt werden Abfrage eine "u_" Konvention
  • Import die Werte übereinstimmen über REST API ServiceNow

PROBLEM:

Die eingebetteten Dokumente haben keine konsistente Struktur. Das Feld HOSTNAME wird in verschiedenen Strukturen gespeichert.

Ich muss den Hostnamen als u_hostname zurückgeben. Ich brauche den Wert von $ hostnames.name falls vorhanden ODER den Wert von $ hostname, falls er existiert.

Wie kann ich feststellen, ob eines existiert, und es als u_hostname zurückgeben?

Struktur 1 Hostname als hostnames.name

$ gespeichert
{ 
    "_id" : "192.168.1.1", 
    "addresses" : { 
     "ipv4" : "192.168.1.1" 
    }, 
    "hostnames" : [ 
     { 
      "type" : "PTR", 
      "name" : "example.hostname.com" 
     } 
    ] 
} 

Struktur 2 Hostnamen als Hostnamen

$ gespeichert
{ 
    "_id" : "192.168.2.1", 
    "addresses" : { 
     "ipv4" : "192.168.2.1" 
    }, 
    "hostname" : "helloworld.com", 

} 

Script:

Die Abfrage wird nur gib den Wert von $ host zurück name, nicht $ hostname.name.

cmp = db['computers'].aggregate([ 
     {"$project" : { 
       "_id":0, 
       "u_hostname": "$hostnames.name", 
       "u_hostname": "$hostname", 
       "u_ipv4": "$addresses.ipv4" 
     }} 
]) 
+0

Ist "Hostnamen" ein Element-Array? – styvane

+0

Nicht sicher, ob ich richtig verstehe, aber ich denke, "Hostnamen" ist ein Array von Objekten. Wie Sie in Struktur 1 sehen können, enthält das Array "hostnames" zwei Eigenschaften "name" und "type". – pengz

+0

Haben Sie immer ein Objekt im Array? – styvane

Antwort

1

können Sie den $ifNull Operator $project der "Hostname" Feld.

cmp = db['computers'].aggregate([ 
    {"$project": { 
     "u_hostname": { 
      "$ifNull": [ 
       "$hostnames.name", 
       { "$map": { 
        "input": {"$literal": ["A"]}, 
        "as": "el", 
        "in": "$hostname" 
       }} 
      ] 
     }, 
     "_id": 0, 
     "u_ipv4": "$addresses.ipv4" 
    }}, 
    {"$unwind": "$u_hostname"} 
]) 
1

Sie möchten die Operatoren $ unwind, $ group und $ setUnion in der Aggregatfunktion enthalten. Es erlaubt Ihnen, die Liste der Hostnamen zu reduzieren und sie dann mit den anderen Hostnamen zu verbinden.