sql >> Database >  >> NoSQL >> MongoDB

Hoe maak je een nieuw matrixveld aan met het aggregatieraamwerk?

In moderne MongoDB-releases is de meest efficiënte manier om de array eenvoudigweg te noteren met behulp van de bestaande documenteigenschappen. Directe notatie van arrays werd geïntroduceerd in MongoDB 3.2:

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

Of zelfs met behulp van $addFields om de nieuwe eigenschap eenvoudig aan de documenten toe te voegen:

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

Als u MongoDB 2.6 en hoger gebruikt, kunt u dit doen met het aggregatieraamwerk en voorkomen dat resultaten in uw clientprogramma worden herhaald om een ​​nieuwe verzameling te maken.

De belangrijkste functie hier die u helpt, is de $out operator voor het verzenden van de uitvoer naar een nieuwe verzameling. Maar ook een beetje slim zijn om de array te maken die je nodig hebt.

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

Dit maakt dus gebruik van de $literal operator om een ​​nieuwe array aan de kop van de pijplijn te specificeren. Deze operator plaatst inhoud in de documenteigenschap exact hoe het wordt geleverd. Er zijn dus geen vervangingen van variabelen toegestaan, vandaar "letterlijk".

Om de "coordintes" -array te maken, wikkelen we eenvoudig die eerste array af, die in wezen twee van elk document maakt met een andere waarde in "type". Dit wordt vervolgens gebruikt in de $group stap naar voorwaardelijk $push ofwel de "$lat" of "$long" waarde op die array.

Gebruik ten slotte $project nogmaals om de documentstructuur af te ronden en dan $out stuurt alle uitvoer naar de nieuwe collectie.

Merk op dat dit alleen zinvol is als het uw bedoeling is om een ​​nieuwe collectie aan te maken en om te voorkomen dat verkeer "over the wire" wordt gestuurd. Dit kan niet puur binnen het aggregatieraamwerk worden gebruikt om uw document opnieuw vorm te geven met de bedoeling om vervolgens een "geo-ruimtelijke" query in diezelfde aggregatiepijplijn uit te voeren, aangezien "geo-ruimtelijke" query's alleen werken wanneer ze daadwerkelijk zijn geïndexeerd op een verzameling .

Dus dit kan je helpen een nieuwe collectie te maken zoals je wilt, maar het dient in ieder geval als voorbeeld (of eigenlijk twee voorbeelden) van hoe je een array kunt maken uit verschillende waarden met het aggregatieraamwerk.



  1. MongoDB Convert String naar Array

  2. Hoe redis-server te starten op een andere poort dan de standaardpoort 6379 in ubuntu

  3. Mongoimport csv-bestanden met string _id en upsert

  4. MongoDB - documenten in een array bijwerken