Dalam rilis MongoDB Modern, cara yang paling efisien adalah dengan hanya memberi notasi pada array menggunakan properti dokumen yang ada. Notasi langsung dari array diperkenalkan di MongoDB 3.2:
db.collection.aggregate([
{ "$project": {
"lat": 1,
"long": 1,
"geometry": {
"type": { "$literal": "Point" },
"coordinates": [ "$lat", "$long" ]
}
}},
{ "$out": "newcollection" }
])
Atau bahkan menggunakan $addFields
untuk sekadar "menambahkan" properti baru ke dokumen:
db.collection.aggregate([
{ "$addFields": {
"geometry": {
"type": { "$literal": "Point" },
"coordinates": [ "$lat", "$long" ]
}
}},
{ "$out": "newcollection" }
])
Jika Anda menggunakan MongoDB 2.6 dan di atasnya, Anda dapat melakukannya dengan kerangka kerja agregasi dan menghindari hasil perulangan dalam program klien Anda untuk membuat koleksi baru.
Fitur utama di sini yang membantu Anda adalah $out
operator untuk mengirim output ke koleksi baru. Tetapi juga menjadi sedikit pintar untuk membuat array yang Anda butuhkan.
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" }
])
Jadi ini menggunakan $literal
operator untuk menentukan array baru di kepala pipa. Operator ini akan menempatkan konten di properti dokumen tepat bagaimana itu disediakan. Jadi tidak ada penggantian variabel yang diperbolehkan, maka "literal".
Untuk membuat larik "koordinat", kita cukup melepas larik pertama yang pada dasarnya membuat dua dari setiap dokumen dengan nilai "tipe" yang berbeda. Ini kemudian digunakan di $group
tahap ke kondisional $push
nilai "$lat" atau "$long" ke dalam larik tersebut.
Terakhir gunakan $project
lagi untuk menyelesaikan struktur dokumen dan kemudian $out
mengirimkan semua output ke koleksi baru.
Perhatikan bahwa ini hanya masuk akal jika niat Anda adalah membuat koleksi baru dan menghindari pengiriman lalu lintas "melalui kabel". Ini tidak dapat digunakan murni dalam kerangka agregasi untuk membentuk kembali dokumen Anda dengan maksud untuk kemudian melakukan kueri "geo-spasial" dalam saluran agregasi yang sama karena kueri "geo-spasial" hanya akan berfungsi ketika benar-benar diindeks pada koleksi .
Jadi ini dapat membantu Anda membuat koleksi baru seperti yang Anda inginkan, tetapi setidaknya ini berfungsi sebagai contoh (atau dua contoh sebenarnya) tentang cara membuat array dari nilai yang berbeda dengan kerangka kerja agregasi.