2016-06-13 17 views
0

Ich schreibe ein Python-Skript, um eine MongoDB-Datenbank abzufragen. Ich benötige Hilfe beim Abfragen, Filtern und Analysieren von Daten, die in assoziativen Arrays gespeichert sind.Anfrage für MongoDB Assoziative Arrays

Anforderungen:

  • Abfrage Hostname, Zuletzt gesehen Datum, Status und IPv4-Adresse (andere Felder nicht erforderlich)

  • die Daten in ein "flaches" json-Format analysiert, die importiert werden können in eine relationale Datenbank ist

Hier wird die Datenstruktur der Daten, die wir abfragen:

[{"hostnames": [{"type": "ABC", "name": "example.hostname.com"}], "vendor": {"vendor_name": "apple"}, "last_seen": {"$date": 1461123503979}, "status": {"state": "up", "reason": "echo-reply"}, "addresses": {"ipv4": "192.168.1.1"}}] 

Hier ist die einfachere Datenstruktur, die ich so wollen, dass sie in eine flache relationale Datenbank importiert werden können:

[{"name": "example.hostname.com", "vendor": "apple", "$date": 1461934503972, "state": "up", "ipv4": "192.168.1.1"}] 

Hier ist der Code, den ich begonnen haben. Ich verwende Aggregation, um Aliase für die Felder zu erstellen.

Ich muss noch die assoziativen Arrays durchlaufen, um die Daten im gewünschten Format abzurufen.

client = MongoClient(mongo_uri) 

db = client[mongo_db] 

computers = db['computer'].aggregate([ 

#Aggregate - RDBMS equivalent to Alias select x as y 
#Rename fields to match destination names 
     {"$project": { 
       "_id":0, 
       "u_id":"$id", 
       "u_status": "$status", 
       "u_vendor":"$vendor", 
       "u_addresses": "$addresses", 
       "u_hostnames": "$hostnames", 
       "u_last_seen": "$last_seen" 
     }} 
    ]) 
+0

Ist "Hostnamen" eine Elementliste? – styvane

+0

Ja, das ist ein Beispiel für ein einzelnes Dokument in der Sammlung. – pengz

+0

Vielen Dank für Ihre Hilfe. Noch eine Frage, das Datum "u_last_seen" wird nicht zurückgegeben. "Datum": "$ last_seen.date" Das Datumsfeld ist codiert. Hier ist ein Beispiel für das Datumsfeld in der Datenbank. "last_seen": ISODate ("2016-04-29T14: 06: 17.441Z") Was muss ich noch tun, um diesen Wert zurückzugeben? Vielen Dank. – pengz

Antwort

1

Sie benötigen den „Host-Namen“ Array $unwind oder verwenden Sie den $arrayElemAt Operator das „Namen“ Feld für das Element in dem Array zuzugreifen, auf dem Server-Version abhängig.

Der optimale Weg ist, in MongoDB 3.2 $arrayElemAt Operator in der $project Stufe mit dem Element in dem Array zurückzubringen, die man dann auf eine Variable eingestellt, die $let Operator und auf das Feld „Name“ mit Punktschreibweise.

computers.aggregate([ 
    {"$project": { 
     "name": { 
     "$let": { 
      "vars": {"host": {"$arrayElemAt": ["$hostnames", 0]}}, 
      "in": "$$host.name"} 
     }, 
     "vendor": "$vendor.vendor_name", 
     "date": "$last_seen.date", 
     "state": "$status.state", 
     "ipv4": "$addresses.ipv4", 
     "_id": 0 
    }} 
]) 

In alte Version, müssen Sie das Array mit dem $unwind Bediener vor $project ing Ihr Dokument dekonstruieren.

computers.aggregate([ 
    {"$unwind": "$hostnames"}, 
    {"$project": { 
     "name": "$hostnames.name", 
     "vendor": "$vendor.vendor_name", 
     "date": "$last_seen.date", 
     "state": "$status.state", 
     "ipv4": "$addresses.ipv4", 
     "_id": 0 
    }} 
])