Turkcell | Geleceği Yazanlar

402: MongoDBBaşlangıç seviyesi derslerde Web Programlama uygulama geliştirme ortamını detaylı olarak inceliyoruz.

Tüm Eğitimleri Aldın mı? Kendini sınamanın tam zamanı

Haydi Sınava Gir

2DSPHERE Index Oluşturma

Kategori : | Lisans : Creative Commons (by-nc-sa) | En son 12.09.2019 tarihinde güncellendi
Eğitmen : mckare
Etiketler : web-programlama

2DSPHERE İNDEKS OLUŞTURMA

GeoSON formatında geospatial (coğrafi mekansal) bir indeks oluşturmak için db.collection.ensureIndex() metodunu kullanmalısınız. Oluşturulacak indeksin 2dsphere türünde olması için bu anahtar sözcüğü komuta eklemelisiniz.

ÖRNEK:

db.collection.ensureIndex( { <İndeks Alanı> : "2dsphere" } )

Aşağıdaki prosedür, GeoJSON veri alanı içeren bir grup belge için 2dsphere indeksleri oluşturulmasını gösteriyor:

PROSEDÜR

Önce YER adlı alanda, GeoJSON Point türünde veri içeren belgeler MEKANLAR adlı bir koleksiyon oluşturuluyor; Koordinat düzeni önce boylam (longitude) sonra enlem (latitude) şeklindedir:

db.MEKANLAR.insert(
{
        YER: {
            type: "Point",
            coordinates: [-72.90, 41.77]
        },
        name: "Central Park",
        SINIF: "Parks"
    }
) 

db.MEKANLAR.insert(
{
        YER: {
            type: "Point",
            coordinates: [-73.908, 43.78]
        },
        AD: "La Guardia Airport",
        SINIF: "Airport"
    }
) 

Bu işlemden sonra da 2dsphere indeks, YER alanı için oluşturulabilir:

db.MEKANLAR.ensureIndex( { YER : "2dsphere" } )

2dSPHERE İNDEKS ALANI İLE BİLEŞİK (COMPOUND) İNDEKS OLUŞTURMA

Bir bileşik indeks alanı, 2dsphere tipi bir indeks alanı ile birlikte geospatial olmayan başka bir indeks alanı da içerebilir. Aşağıdaki örnekte 2dsphere türünde geospatial YER alanı ile birlikte geospatial olmayan SINIF ve AD alanları da bileşik indeks oluşturmakta birlikte kullanılmıştır:

db.MEKANLAR.ensureIndex( { YER : "2dsphere" , SINIF : -1, AD: 1 } )

Burada 1 değerinin artan (ascending) -1 değerinin de azalan (descending) anlamında olduğunu bir kez daha hatırlatalım.

2d türü indeksten farklı olarak bileşik bir 2dsphere indeksinde YER bilgisinin ilk alan olması gerekmez.

ÖRNEK:

db.MEKANLAR.ensureIndex( { SINIF : 1 , YER : "2dsphere" } )

BİR 2dSPHERE İNDEKSİ İLE SORGULAMA (QUERY)

Aşağıda, 2dsphere indeksleri ile desteklenen bir MongoDB içinde sorgulamaların nasıl gerçekleştirilebileceğine dair kalıplar verilmektedir:

BİR ÇOKGEN (POLYGON) İLE SINIRLANMIŞ  GeoJSON NESNELERİ

$geoWithin  operatörü sayesinde bir GeoJSON poligonu içindeki yer verileri ile ilişkili sorgulama gerçekleştirilebilir. Yer verisi, GeoJSON formatında saklanmış olmalıdır. Sorgunun yazılış biçimi, aşağıdaki gibidir:

db.<collection>.find( { <location field> :                          { $geoWithin :                            { $geometry :                              { type : "Polygon" ,                                coordinates : [ <coordinates> ]                       } } } } )

Aşağıdaki örnek, bir GeoJSON çokgeni içindeki bütün nokta ve şekilleri seçiyor:

db.places.find( { loc : { $geoWithin : { $geometry :{ type : "Polygon" ,coordinates : [ [[ 0 , 0 ] ,[ 3 , 6 ] ,[ 6 , 1 ],[ 0 , 0 ]] ]} } } } )

GeoJSON  NESNELERİNİN ARAKESİTLERİ (INTERSECTION)

$geoIntersects operatörü yardımı ile, belirli bir GeoJSON nesnesi ile arakesiti olan bölgeler sorgulanabilir:

db.<collection>.find( { <location field> :{ $geoIntersects :{ $geometry :{ type : "<GeoJSON object type>" ,coordinates : [ <coordinates> ]} } } } )

Aşağıdaki örnek ise coordinates dizisi ile belirlenmiş çokgen ile kesişen bütün nokta ve şekilleri sorgulamaktadır:

db.places.find( { loc :{ $geoIntersects :{ $geometry : { type : "Polygon" ,coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] ,[ 6 , 1 ] ,  [ 0 , 0 ]  ] ] } } } } )

 

BİR GeoJSON  NOKTASINA YAKINLIK

 

Yakınlık (proximity) sorguları verilen bir noktaya en yakın olan noktaları bulur ve bunları uzaklıklarına göre sıralı olarak listeler.

Bir GeoJSON verisi üzerindeki uzaklık sorgusu,2dsphere türü bir indeksin oluşturulmasını gerekli kılar.

GeoJSON noktasına yakınlık sorgusu için, MongoDB, $near  operatörünü ya da geoNear komutunu kullanır.Uzaklıklar metre cinsindendir.

$near operatörü aşağıdaki yazılış biçimini kullanmaktadır:

db.<collection>.find( { <location field> :{ $near :{ $geometry : { type : "Point" , coordinates : [ <longitude> , <latitude> ] } , $maxDistance : <distance in meters> } } } )

geoNear komutu ise aşağıdaki yazılış biçiminde kullanılır:

db.runCommand( { geoNear : <collection> ,near : { type : "Point" , coordinates: [ <longitude>, <latitude> ] } ,spherical : true } )

geoNear komutunun, $near operatörüne göre daha çok seçeneği vardır ve daha çok bilgi gönderir.

 

BİR KÜRE ÜZERİNDEKİ BİR DAİRE İÇİNDEKİ NOKTALAR

Bir küre üzerindeki bir küresel kep (spherical cap) içindeki tüm grid koordinatlarını seçmek için $geoWithin operatörünü $centerSphere operatörü ile birlikte kullanmalısınız. Aşağıdaki bilgileri içeren bir dizi (array) oluşturunuz:

a)Dairenin merkezine ait grid koordinatları

b)Radyan cinsinden ölçülmüş dairenin yarıçapı.

Aşağıdaki yazılış biçimini kullanmalısınız:

db.<collection>.find( { <location field> :{ $geoWithin :{ $centerSphere :[ [ <x>, <y> ] , <radius> ] } } } )

 

KÜRESEL GEOMETRİYİ KULLANARAK UZAKLIK HESAPLAMAK

Verinizde boylam ve enlem bilgileri varsa,küresel hesaplamalar yapmak için 2dsphere indekslerini devreye sokmanız gerekir.

2d indeksleri,Öklid(Euclidean) düzleminde uzaklıkları hesaplayan sorgular gerçekleştirebilir.

Küresel geometriyi kullanarak uzaklıklar hesaplamak içinse aşağıdaki operator ve komutlar kullanılır:

$nearSphere

$centerSphere

$near

geoNear  { spherical: true } opsiyonu ile

UZAKLIĞI RADYANA DÖNÜŞTÜRME:

Radyan=Uzaklık/Yarıçap

Bağıntısı kullanılır. Uzaklık ve yarıçap aynı birimde olmalıdır. Dünya üzerinde işlem yapılıyorsa doğal olarak yarıçap dünyanın yarıçapıdır.

RADYANI UZAKLIĞA DÖNÜŞTÜRMEK

Uzaklık=Radyan*Yarıçap

Dünyanın yarıçapı yaklaşık olarak   r=3959 mil  ya da r=6731 km’dir.

Aşağıdaki örnekte merkezi -76,45.00 ve yarıçapı r=110 mil olarak tanımlanmış  daire içinde, YERLER adlı koleksiyondaki belgeler sorgulanmaktadır:

db.YERLER.find( { loc: { $geoWithin: { $centerSphere: [ [ -76, 45.00 ],110 / 3959 ] } } } )

Aşağı sorgu ile de YERLER adlı koleksiyonda, -75,45 merkezli ve 110 mil yarıçaplı bir bölgeye ait belgeler listelenmektedir:

db.runCommand( { geoNear: "places",near: [ -75, 45 },110/3959], spherical: true})

MESAFE  ÇARPANI

geoNear komutunun distanceMultiplier seçeneği kullanılırsa, MongoDB dönüştürülmüş değerleri gönderir ve uygulama içinde dönüşüme gerek kalmaz.

Aşağıdaki örnekte distanceMultiplier  kullanılmakta ve böylece geoNear komutunun radyan-mesafe dönüşümüne küresel sorgularda gerek kalmamaktadır.

db.runCommand({ geoNear: "YERLER",near: [ -75, 45 ],spherical: true,distanceMultiplier: 3959})