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.