6

アマゾンウェブサービスSimpleDBで空間クエリを実行する効率的な方法として人々が提案するものを知りたいですか?

空間クエリとは、緯度と経度の特定の半径にあるオブジェクトを見つけることを意味します。

4

2 に答える 2

14

SimpleDBは現在、組み込みの空間検索操作を提供していませんが、それが実行できないという意味ではありません。SimpleDBなどの地理空間を認識しないデータベースに地理空間検索を実装する方法はいくつかありますが、それらはすべて、データベースを使用して地理空間バウンディングボックスに基づいて最初の大まかな選択を取得し、アプリケーションで返されたデータをフィルタリングするというアイデアを中心にしています。Haversine式などのより正確なアルゴリズム。

緯度と経度を(ゼロが埋め込まれ正規化された)数値属性として格納してから、ダブルレンジクエリ()を実行できますlat >= minLat and lat <= maxLat and lon >= minLat and lon <= maxLatこれらの述語はどちらも選択的ではないため(各述語は多くの項目に一致します)、理想的ではありません(クエリの調整を参照)。 )。

より良い方法は、GeoHashesを使用することです。

ジオハッシュは、任意精度、近くの位置の同様のプレフィックス、コードの末尾から文字を徐々に削除してサイズを縮小する(そして徐々に精度を失う)などのプロパティを提供します。

実際の例として、Geohash 6gkzwgjzn820は座標-25.382708と-49.265506にデコードしますが、Geohash 6gkzwgjzは-25.383と-49.266にデコードし、同じ領域で-25.427と-49.315などの同様の位置を取る場合、6gkzmg1wとしてエンコードされていることがわかります(同様のプレフィックスに注意してください)。

http://geohash.org/site/tips.htmlから

アイテムの位置をGeoHashesとして使用すると、演算子を使用likeしてバウンディングボックス(where GeoHash like '6gkzmg1w%')を検索できますが、like演算子は高価であるため(比較演算子)、各GeoHashプレフィックスレベル(数は必要な検索精度)を個別の属性(GeoHash6 GeoHash8など)として使用し、単純な等式述語(where Geohash8 = '6gkzmg1w')を使用します。

次に、GeoHashesの欠点について説明します。ジオハッシュが検索ボックスの中央に配置されているとは想定できないため、隣接するすべてのプレフィックスも検索する必要があります。プロセスはgeohash-jsによってうまく説明されています

ジオハッシュには、桁数が少なくなると(右から)精度が低下するという特性もあります。互いに近いポイントは同様のジオハッシュプレフィックスを共有するため、このプロパティを使用してバウンディングボックス検索を実行できます。

ただし、特定のポイントが特定のジオハッシュバウンディングボックスの端に表示される場合があるため、ポイントの周囲で真の近接検索を実行するには、ジオハッシュ値のリストを生成する必要があります。ジオハッシュアルゴリズムはbase-32番号付けシステムを使用するため、単純なルックアップテーブルを使用して、他の特定のジオハッシュ値を囲むジオハッシュ値を導出できます。

したがって、たとえば、ワシントンDCのペンシルバニアアベニュー1600は、38.897、-77.036に解決されます。

ジオハッシュアルゴリズムを使用して、この緯度と経度は次のように変換されます:dqcjqcp84c6e

このポイントの周りの単純なバウンディングボックスは、このジオハッシュを次のように切り捨てることで説明できます。dqcjqc

ただし、「dqcjqcp84c6e」は「dqcjqc」の中央に配置されていないため、「dqcjqc」内を検索すると、目的のターゲットが失われる可能性があります。

したがって、代わりに、ジオハッシュの数学的プロパティを使用して、「dqcjqc」の近傍をすばやく計算できます。'dqcjqf'、'dqcjqb'、'dqcjr1'、'dqcjq9'、'dqcjqd'、'dqcjr4'、'dqcjr0'、'dqcjq8'

これにより、「dqcjqcp84c6e」の周囲に約2km x 1.5kmの境界ボックスが表示され、9つのキーでデータベース検索が可能になります。SELECT* FROM table WHERE LEFT(geohash、6)IN('dqcjqc'、'dqcjqf'、'dqcjqb' 、'dqcjr1'、'dqcjq9'、'dqcjqd'、'dqcjr4'、'dqcjr0'、'dqcjq8');

SimpleDBクエリに変換するとwhere GeoHash6 in('dqcjqc', 'dqcjqf', 'dqcjqb', 'dqcjr1', 'dqcjq9', 'dqcjqd', 'dqcjr4', 'dqcjr0', 'dqcjq8')、検索範囲内にあるアイテムのみを取得するために、結果に対してHaversineフィルタリングを実行します。

于 2012-08-08T12:08:22.003 に答える
0

それがあなたを助けるかもしれないので、私はこれをここに残すつもりです!

14年前、半径内の場所の地理ルックアップテーブルを作成しようとしました。明らかに地理空間インデックスなどはありませんでした。文字通り標準のSQLとOracleしかありませんでした...とにかく、すべてのlat/lngを固定平面フィールドからキロメートルに変換することになりました。基本的に、最近の地理空間インデックスは何をしますか。

それが何をするのかを正確に説明すると、それは世界を平らな表面に変え、半径で選択することさえできる少しのSQLのトリックで、選択している2つのポイントからの距離さえも取得できます。それは生の完全な整数でもあるので、クエリは非常に高速です。

これはPHPの簡単な例で、非常に複雑に見えますが、SQLクエリを理解すれば非常に簡単です。

https://gist.github.com/tobsn/899413

于 2015-09-01T11:21:17.160 に答える