MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

So erstellen Sie ein neues Array-Feld mit dem Aggregat-Framework

In modernen MongoDB-Releases besteht die effizienteste Methode darin, das Array einfach mit den vorhandenen Dokumenteigenschaften zu notieren. Die direkte Notation von Arrays wurde in MongoDB 3.2 eingeführt:

db.collection.aggregate([
  { "$project": {
    "lat": 1,
    "long": 1,
    "geometry": {
      "type": { "$literal": "Point" },
      "coordinates": [ "$lat", "$long" ]
    }
  }},
  { "$out": "newcollection" }
])

Oder sogar mit $addFields um die neue Eigenschaft einfach an die Dokumente "anzuhängen":

db.collection.aggregate([
  { "$addFields": {
    "geometry": {
      "type": { "$literal": "Point" },
      "coordinates": [ "$lat", "$long" ]
    }
  }},
  { "$out": "newcollection" }
])

Wenn Sie MongoDB 2.6 und höher verwenden, können Sie dies mit dem Aggregations-Framework tun und Schleifenergebnisse in Ihrem Client-Programm vermeiden, um eine neue Sammlung zu erstellen.

Die Hauptfunktion hier, die Ihnen hilft, ist $ aus -Operator zum Senden der Ausgabe an eine neue Sammlung. Aber auch ein wenig schlau sein, um das Array zu erstellen, das Sie brauchen.

db.collection.aggregate([
    { "$project": {
        "lat": 1,
        "long": 1,
        "type": { "$literal": ["lat","long"] }
    }},
    { "$unwind": "$type" },
    { "$group": {
        "_id": "$_id",
        "lat": { "$first": "$lat" },
        "long": { "$first": "$long" },
        "coordinates": {
            "$push": {
                "$cond": [
                    { "$eq": [ "$type", "lat" ] },
                    "$lat",
                    "$long"
                ]
            }
        }
    }},
    { "$project": {
        "lat": 1,
        "long": 1,
        "geometry": { 
            "type": { "$literal": "Point" },
            "coordinates": "$coordinates"
        }
    }},
    { "$out": "newcollection" }
])

Dies nutzt also den $literal -Operator, um ein neues Array am Kopf der Pipeline anzugeben. Dieser Operator fügt Inhalte genau in die Dokumenteigenschaft ein wie es geliefert wird. Daher sind keine Variablenersetzungen erlaubt, daher "literal".

Um das Array „coordintes“ zu erstellen, wickeln wir einfach das erste Array ab, das im Wesentlichen zwei von jedem Dokument mit einem unterschiedlichen Wert in „type“ erstellt. Dieser wird dann in der $group Schritt zu bedingt $push entweder den Wert "$lat" oder "$long" auf dieses Array.

Verwenden Sie schließlich $project erneut, um die Dokumentstruktur abzuschließen, und dann $out sendet alle Ausgaben an die neue Sammlung.

Beachten Sie, dass dies nur sinnvoll ist, wenn Sie beabsichtigen, eine neue Sammlung zu erstellen und zu vermeiden, dass Datenverkehr „über die Leitung“ gesendet wird. Dies kann nicht nur innerhalb des Aggregationsframeworks verwendet werden, um Ihr Dokument mit der Absicht neu zu gestalten, dann eine „geo-räumliche“ Abfrage in derselben Aggregationspipeline durchzuführen, da „geo-räumliche“ Abfragen nur funktionieren, wenn sie tatsächlich in einer Sammlung indiziert sind .

Dies kann Ihnen also helfen, eine neue Sammlung zu erstellen, wie Sie möchten, aber zumindest dient es als Beispiel (oder eigentlich zwei Beispiele) dafür, wie Sie mit dem Aggregationsframework ein Array aus verschiedenen Werten erstellen.