sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur man skapar ett nytt arrayfält med det aggregerade ramverket

I moderna MongoDB-utgåvor är det mest effektiva sättet att helt enkelt notera arrayen med de befintliga dokumentegenskaperna. Direkt notation av arrayer introducerades i MongoDB 3.2:

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

Eller till och med använda $addFields för att helt enkelt "lägga till" den nya egenskapen till dokumenten:

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

Om du använder MongoDB 2.6 och senare kan du göra detta med aggregeringsramverket och undvika looping av resultat i ditt klientprogram för att skapa en ny samling.

Huvudfunktionen här som hjälper dig är $ ut operatör för att skicka utdata till en ny samling. Men också att vara lite smart för att skapa den array som du behöver.

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å detta använder sig av $literal operatör för att ange en ny array i spetsen av pipelinen. Denna operatör kommer att placera innehållet i dokumentegenskapen exakt hur den levereras. Så inga variabelsubstitutioner är tillåtna, därav "bokstavligen".

För att skapa "coordintes" arrayen, kopplar vi helt enkelt upp den första arrayen som i huvudsak skapar två av varje dokument med ett annat värde i "type". Detta används sedan i $group steg för att villkorligt $push antingen värdet "$lat" eller "$long" på den arrayen.

Använd slutligen $project igen för att slutföra dokumentstrukturen och sedan $out skickar all utdata till den nya samlingen.

Observera att detta bara är vettigt om din avsikt är att skapa en ny samling och undvika att skicka trafik "över tråden". Detta kunde inte användas enbart inom aggregeringsramverket för att omforma ditt dokument med avsikten att sedan göra en "geo-spatial" fråga i samma aggregeringspipeline eftersom "geo-spatiala" frågor bara fungerar när de faktiskt indexeras på en samling .

Så det här kan hjälpa dig att skapa en ny samling som du vill, men den fungerar åtminstone som exempel (eller två exempel faktiskt) på hur man skapar en array av olika värden med aggregeringsramverket.



  1. Ställ in Cache Redis Expiration till 1 år

  2. DIY Cloud Database on Amazon Web Services - New Whitepaper

  3. Återställ en mongodb i meteorproduktionsserver

  4. Hur man hittar slumpmässiga poster i Mongoose