Google App Engin (JAVA) でぶち当たった問題 その4
緯度、経緯を利用したGISのアプリの場合、ある地域または区間(メッシュ)に登録されているデータを取り出そうとして通常のSQLであれば
SELECT m FROM Marker WHERE m.lat BETWEEN 36.21 and 24.44 AND m.lng BETWEEN 36.31 and 24.54
で検索を行うことが出来るのですが、BigTableの場合には検索出来ません。
Restrictions on Queries:クエリーの制限規定
上記のGoogle App Enginedドキュメントには”Inequality Filters Are Allowed On One Property Only”
意訳ですが比「較式は一つの属性のみに受つけられます。」 なんだかよくわからない訳ですので。実際にコードを見た方が早いかと思います。
A query may only use inequality filters (<, <=, >=, >) on one property across all of its filters.
たとえば
select from Person where birthYear >= minBirthYearParam
&& birthYear <= maxBirthYearParam
は問題なくBigTableで検索がおこなえます。
なぜなら>=と<=が各一つのみだからです。
こちらは?
select from Person where birthYear >= minBirthYearParam
&& height >= minHeightParam // ERROR
はエラーとなります。
なぜなら>=が2つあるので。
equal (==)についてはその限りではありません。
select from Person where lastName == lastNameParam
&& city == cityParam
&& birthYear >= minBirthYearParam
問題なく処理されます。
もとい
SELECT m FROM Marker WHERE m.lat BETWEEN 36.21 and 24.44 AND m.lng BETWEEN 36.31 and 24.54
を実行する場合にはGeohashアルゴリズムを利用して検索を行うことでBigTableの制限を回避してすることが出来るようです。
http://en.wikipedia.org/wiki/Geohash
JAVAの実装サンプル。
http://code.google.com/p/geospatialweb/source/browse/trunk/geohash/src/Geohash.java?r=104
こんな問題にぶち当たるとやはり・アルゴリズムデザインを再度勉強しなければとつくづく思います。