Agar valid untuk "kueri geospasial" "lokasi" harus dalam bujur, lintang urutan dan tidak dapat berisi koordinat lain.
Format yang valid adalah
{
"location": [long,lat]
}
Atau
{
"location": { "lng": long, "lat": lat }
}
Atau GeoJSON
{
"location": {
"type": "Point",
"coordinates": [long,lat]
}
}
Bidang lain seperti "radius" adalah "bidang lain" dan tidak bisa menjadi bagian dari array yang sama.
Idealnya ikuti GeoJSON:
{
"location": {
"type": "Point",
"coordinates": [long,lat]
},
"radius": radius
}
Yang dalam definisi skema luwak bisa sesederhana:
var geoSchema = new Schema({
"location": {
"type": String,
"coordinates": []
},
"radius": Number
});
Saat menangani data geospasial pada koordinat "globe" nyata, indeks Anda harus "2dsphere" , yang secara opsional Anda definisikan pada skema sebagai :
geoSchema.index({ "location": "2dsphere" })
Karena tidak ada dukungan sebenarnya untuk objek "Lingkaran" di GeoJSON yang didukung, maka disarankan untuk menyimpan bidang lain sebagai "jari-jari" dan menyimpan "titik pusat".
Keuntungan "besar" dengan GeoJSON dibandingkan format "pasangan koordinat lama" lainnya adalah ketika mengembalikan sesuatu seperti "jarak" dari suatu titik melalui geoNear
atau $geoNear
maka "jarak" itu didefinisikan dalam "meter" secara konsisten. Ini juga cara Anda harus menentukan nilai "radius" apa pun di penyimpanan Anda agar tetap konsisten dengan hasil tersebut.
Dengan format penyimpanan lain maka hasilnya dikembalikan dalam "radian", yang mungkin ingin Anda konversi dan lebih suka untuk tidak menyimpan "radius" lingkaran dengan itu sebagai pengukuran.
Cara mengatasinya adalah dengan mempertimbangkan data dalam bentuk ini:
{
"locationtype": "circle",
"location": {
"type": "Point",
"coordinates": [1,1]
},
"radius": 4
}
Kemudian Anda menggunakan .aggregate()
dengan $geoNear
panggung dan $redact
untuk memfilter:
db.collection.aggregate([
// Find points or objects "near" and project the distance
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [2,2]
},
"distanceField": "distance",
"query": { "locationType": "circle" }
}},
// Logically filter anything outside of the radius
{ "$redact": {
"$cond": {
"if": { "$gt": [ "$distance", "$radius" ] },
"then": "$$PRUNE",
"else": "$$KEEP"
}
}}
])
Sekarang nilai yang digunakan dalam contoh kueri hanyalah sebuah contoh, tetapi seperti yang dinyatakan dengan koordinat "nyata" bujur dan lintang, atribut "jarak" berfungsi seperti yang dirancang dan dalam toleransi "meter" seperti yang disebutkan sebelumnya.
Poinnya di sini adalah $geoNear
keduanya akan menemukan "dekat" ke titik pusat "lingkaran" tidak peduli apa jenis objeknya. Tidak hanya itu tetapi perintah di sini menghasilkan "proyeksi" bidang lain dalam dokumen di sini seperti yang disebutkan dalam "distanceField". Ini mewakili jarak dari lingkaran "pusat" dalam "meter".
Tahap kedua di sini menggunakan $redact
karena ini seperti $project
dan $match
tahap pipa dalam satu. Tidak seperti $match
operator ini dapat mengevaluasi kondisi "logis" dengan membandingkan bidang yang ada dalam dokumen. Dalam hal ini, operasi seperti $$PRUNE
hapus dokumen yang cocok ke kondisi "jika" di mana true
dan "hapus" dari hasil atau sebaliknya $$KEEP
dokumen yang kondisinya false
.
Singkatnya, jika "jarak" adalah "lebih besar dari" maka "jari-jari" dari "lingkaran" maka objek "terletak di luar" lingkaran dan tidak "berpotongan". Jika tidak, "ya".
Jadi itulah dasar-dasar "mendefinisikan 'lingkaran' untuk geometri dalam kumpulan dan "menggunakannya" untuk mencapai sesuatu seperti persilangan antara "Titik" atau jenis Objek lain dalam radius "lingkaran".