sql >> データベース >  >> NoSQL >> MongoDB

地理空間クエリは配列で機能しますか? ($ geoWithin、$ geoIntersects)

    これは、「はい」と「いいえ」の両方の質問の1つです。「はい」では、結果の照合に配列がサポートされていますが、照合方法の制限を考慮すると、おそらく実際には必要ないものです。

    ここで必要な注目すべき変更は、オブジェクト自体が、現在形成されているオブジェクトをMongoDBが認識するように定義されていないことです。 2つのインデックスと一般的なルックアップフォームがあり、レガシー座標ペア(x、yポイントのみ)または GeoJSON サポートされているGeoJSONオブジェクトを使用します。問題は、仕様に実際には準拠していない「疑似」GeoJSON形式があり、「座標」に直接アクセスしようとしていることです。このようなトップレベルのオブジェクトが必要です。

    {
        "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
                        ]
                    ]]
                }
            }
        ]
    }
    

    これにより、GeoJSONの部分が抽象化され、整形式であり、仕様の一部ではない他のメタデータから分離されます。 $geoWithinには必須ではありませんが、理想的にはインデックスも作成します。 または$geoIntersects それは確かに役立ちます:

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

    配列要素内のGeoJSON定義へのフルパスを定義します。

    その後、クエリは適切に機能します:

    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]
                    ]]
                }
            }
        }
    })
    

    上記のドキュメントと一致します。しかしもちろん、配列には複数のオブジェクトがあるので、問題は、これらのどれが一致したかということです。 MongoDBは「ドキュメント」と一致しており、どの配列要素が一致したかをまったく示していないため、サポートされている回答はありません。

    集計にはオプションがあります $geoNear これにより、一致したオブジェクトを返すことができます。この場合、「最も近い」オブジェクトになります。そして、そのような詳細で、その情報を使用して、完全なメタデータを持つどの配列要素に「最も近い」ものとして見つかった要素が含まれているかを照合し、そのデータを抽出することができます。ただし、これも「近い」だけであり、配列から複数の結果を返すことはできません。

    ただし、一般的に言えば、個別のオブジェクトを独自のコレクション内のドキュメントとして分離する方が適切です。個別のオブジェクトとの一致は、ドキュメントの一致の問題です。したがって、上記の配列を独自のコレクションに入れて、一致するジオメトリのクエリを発行するだけです。

    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]
                    ]]
                }
            }
        }
    })
    

    この場合、形状が両方と交差するため、正しいオブジェクトが得られます。

    {
        "_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
                ]
            ]]
        }
    }
    

    したがって、配列を使用することはできますが、実際に一致させることができるのはドキュメントのみであり、一致の一部であった個々の配列メンバーは一致しないため、もちろんドキュメント全体が返され、クライアントコードの基準に一致するメンバーを特定する必要があります。 。

    別の注意点として、クエリの試行のいくつかは、オブジェクト座標配列を個々の要素に「分割」しようとします。オブジェクトは全体としてのみ処理でき、「ポイント」部分としては処理できないため、これはまったくサポートされていません。




    1. MongoDBとSpringでソフト(論理)削除を実装するにはどうすればよいですか?

    2. MongoDBがインデックス交差を使用しないのはなぜですか?

    3. mongodbphpアップデートのarrayFilters

    4. 個別のオブジェクトとして保存されたEmber-data埋め込みオブジェクト