sql >> Database teknologi >  >> NoSQL >> MongoDB

Sådan opretter du et nyt arrayfelt med den samlede ramme

I moderne MongoDB-udgivelser er den mest effektive måde blot at notere arrayet ved hjælp af de eksisterende dokumentegenskaber. Direkte notation af arrays blev introduceret i MongoDB 3.2:

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

Eller endda ved at bruge $addFields for blot at "føje" den nye egenskab til dokumenterne:

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

Hvis du bruger MongoDB 2.6 og nyere, kan du gøre dette med aggregeringsrammerne og undgå at sløjfe resultater i dit klientprogram for at oprette en ny samling.

Den vigtigste funktion her, der hjælper dig, er $ ud operatør for at sende output til en ny samling. Men også at være lidt klog for at skabe det array, du har brug for.

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" }
])

Så dette gør brug af $literal operatør for at specificere et nyt array i spidsen af ​​pipelinen. Denne operatør vil placere indhold i dokumentegenskaben præcis hvordan det leveres. Så ingen variable substitutioner er tilladt, derfor "bogstaveligt".

For at skabe "coordintes"-arrayet afvikler vi simpelthen det første array, som i det væsentlige skaber to af hvert dokument med en anden værdi i "type". Dette bruges derefter i $group trin til betinget $push enten "$lat" eller "$long" værdien på det array.

Brug endelig $project igen for at færdiggøre dokumentstrukturen og derefter $out sender alt output til den nye samling.

Bemærk, at dette kun giver mening, hvis din hensigt er at oprette en ny samling og undgå at sende trafik "over the wire". Dette kunne ikke bruges udelukkende inden for aggregeringsrammen til at omforme dit dokument med den hensigt at lave en "geo-spatial" forespørgsel i den samme aggregeringspipeline, da "geo-spatial" forespørgsler kun vil fungere, når de faktisk er indekseret på en samling .

Så dette kan hjælpe dig med at oprette en ny samling, som du vil, men det fungerer i det mindste som eksempel (eller faktisk to eksempler) på, hvordan man opretter et array ud fra forskellige værdier med aggregeringsrammen.



  1. MongoDB NU Aggregationsvariabel

  2. Mongoose $lookup hvor localField er en streng af et ObjectId i fremmedField

  3. MongoDB findOneAndDelete()

  4. Håndtering af langvarige operationer i MongoDB