MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Apakah kueri geospasial berfungsi pada array? ( $geoWithin, $geoIntersects )

Ini adalah salah satu dari pertanyaan ya dan tidak untuk dijawab, karena ya array didukung untuk hasil yang cocok tetapi juga mungkin bukan yang Anda inginkan mengingat pembatasan tentang cara pencocokan dilakukan.

Perubahan penting yang Anda butuhkan di sini adalah bahwa objek itu sendiri tidak didefinisikan sedemikian rupa sehingga MongoDB akan mengenalinya seperti yang Anda buat saat ini. Ada dua indeks dan formulir pencarian umum dengan pasangan koordinat lama ( yang hanya berupa titik x,y ) atau sebagai GeoJSON dengan objek GeoJSON yang didukung. Masalah Anda adalah Anda memiliki format GeoJSON "psuedo" yang tidak benar-benar sesuai dengan spesifikasi, dan Anda mencoba mengakses "koordinat" secara langsung, di mana Anda memerlukan objek tingkat atas seperti:

{
    "regions": [
        {
            "name": "penta",
            "geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [ 
                        -77.0322804898023610, 
                        -12.1271067552781560
                    ], 
                    [ 
                        -77.0336792618036270, 
                        -12.1255133434450870
                    ], 
                    [ 
                        -77.0326449349522590, 
                        -12.1239143495252150
                    ], 
                    [ 
                        -77.0300991833209990, 
                        -12.1238251884504540
                    ], 
                    [ 
                        -77.0299865305423740, 
                        -12.1262000752832540
                    ], 
                    [ 
                        -77.0322804898023610, 
                        -12.1271067552781560
                    ]
                ]]
            }
        },
        {
            "name": "triangle",
            "geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [ 
                        -77.0313568040728570, 
                        -12.1266573492018090
                    ], 
                    [ 
                        -77.0325788855552670, 
                        -12.1246968022373030
                    ], 
                    [ 
                        -77.0300653204321860, 
                        -12.1246233756874440
                    ], 
                    [ 
                        -77.0313568040728570, 
                        -12.1266573492018090
                    ]
                ]]
            }
        }
    ]
}

Sehingga mengabstraksikan bagian GeoJSON agar terbentuk dengan baik dan terpisah dari meta data lain yang bukan merupakan bagian dari spec. Idealnya Anda juga akan mengindeks, meskipun tidak diperlukan untuk $geoWithin atau $geoIntersects itu pasti membantu:

db.regions.createIndex({ "regions.geometry": "2dsphere" })

Mendefinisikan path lengkap ke definisi GeoJSON dalam elemen array.

Kemudian kueri berfungsi dengan baik:

db.regions.find({
    "regions.geometry" : { 
        "$geoIntersects" : { 
            "$geometry" : { 
                "type" : "Polygon" , 
                "coordinates" : [[
                    [ -77.02877718955278 , -12.123750122669545],
                    [ -77.03457042574883 , -12.123750122669545],
                    [ -77.03457042574883 , -12.12736341792724],
                    [ -77.02877718955278 , -12.12736341792724], 
                    [ -77.02877718955278 , -12.123750122669545]
                ]]
            }
        }
    }
})

Yang cocok dengan dokumen di atas. Tapi tentu saja ada beberapa objek dalam array, jadi pertanyaannya adalah, mana yang cocok? Tidak ada jawaban yang didukung, karena MongoDB mencocokkan "dokumen" dan tidak menunjukkan elemen array mana yang cocok.

Ada opsi dalam agregasi $geoNear yang memungkinkan objek yang cocok untuk dikembalikan, di mana dalam hal ini akan menjadi "terdekat". Dan dengan detail seperti itu kemudian dimungkinkan untuk menggunakan informasi itu untuk mencocokkan elemen array mana dengan data meta lengkap yang berisi elemen yang ditemukan untuk "terdekat" dan mengekstrak data itu. Tapi sekali lagi itu hanya "dekat" dan juga tidak pernah bisa mengembalikan lebih dari satu hasil dari sebuah array.

Tetapi secara umum lebih baik untuk memisahkan objek sebagai dokumen dalam koleksi mereka sendiri, di mana kecocokan dengan objek yang berbeda hanyalah masalah pencocokan dokumen. Jadi dengan array di atas dalam koleksinya sendiri, Anda cukup mengeluarkan kueri untuk geometri yang cocok:

db.shapes.find({
    "geometry" : { 
        "$geoIntersects" : { 
            "$geometry" : { 
                "type" : "Polygon" , 
                "coordinates" : [ [ 
                    [ -77.02877718955278 , -12.123750122669545],
                    [ -77.03457042574883 , -12.123750122669545],
                    [ -77.03457042574883 , -12.12736341792724],
                    [ -77.02877718955278 , -12.12736341792724], 
                    [ -77.02877718955278 , -12.123750122669545]
                ]]
            }
        }
    }
})

Yang memberikan objek yang benar karena dalam hal ini bentuknya berpotongan dengan keduanya:

{
    "_id" : ObjectId("55f8d2fa66c2e7c750414b7a"),
    "name" : "penta",
    "geometry" : {
        "type" : "Polygon",
        "coordinates" : [[
            [
                    -77.03228048980236,
                    -12.127106755278156
            ],
            [
                    -77.03367926180363,
                    -12.125513343445087
            ],
            [
                    -77.03264493495226,
                    -12.123914349525215
            ],
            [
                    -77.030099183321,
                    -12.123825188450454
            ],
            [
                    -77.02998653054237,
                    -12.126200075283254
            ],
            [
                    -77.03228048980236,
                    -12.127106755278156
            ]
        ]]
    }
}
{
    "_id" : ObjectId("55f8d2fa66c2e7c750414b7b"),
    "name" : "triangle",
    "geometry" : {
        "type" : "Polygon",
        "coordinates" : [[
            [
                    -77.03135680407286,
                    -12.126657349201809
            ],
            [
                    -77.03257888555527,
                    -12.124696802237303
            ],
            [
                    -77.03006532043219,
                    -12.124623375687444
            ],
            [
                    -77.03135680407286,
                    -12.126657349201809
            ]
        ]]
    }
}

Jadi Anda dapat menggunakan array tetapi Anda hanya dapat benar-benar mencocokkan dokumen dan bukan anggota array individu yang merupakan bagian dari pertandingan, jadi ini akan mengembalikan dokumen kursus secara keseluruhan dan Anda perlu mencari tahu anggota mana yang cocok dengan kriteria dalam kode klien .

Pada catatan lain, beberapa kueri Anda mencoba untuk "memecah" array koordinat objek menjadi elemen individual. Ini tidak didukung sama sekali karena objek hanya dapat ditangani secara keseluruhan dan bukan sebagai bagian "Titik".




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mengindeks array paralel di Mongodb

  2. Kelompokkan Nilai dan Hitungan Berbeda untuk Setiap Properti dalam Satu Kueri

  3. Tidak sama di mongo mapper

  4. mgo - kinerja kueri tampaknya lambat secara konsisten (500-650 ms)

  5. Bagaimana cara menggunakan sql seperti di PyMongo?