1

Rails 3+、Heroku、Pgsql で実行していて、Maxmind の Geoipデータベースを使用している人はいますか?

MySql では、次の方法で簡単なクエリを実行できました。

IpToCountry.where('ip_to_countries.ip_number_to >= INET_ATON(?)', '24.24.24.24').order('ip_number_to ASC').limit(1).first

ただし、Pgsql に移行してから、db を適切にクエリする方法を見つけようとしています。これまでのところ、私は持っています:

remote_ip_array = '24.24.24.24'.split('.')
remote_ip_number = 16777216*remote_ip_array[0].to_i + 65536*remote_ip_array[1].to_i + 256*remote_ip_array[2].to_i + remote_ip_array[3].to_i
ip_to_country = IpToCountry.where('? >= ip_number_from AND ? <= ip_number_to', remote_ip_number, remote_ip_number).order('ip_number_to ASC').limit(1).first

上記のクエリの問題は、一部の IP が一致しないことです。例:37.59.16.123108.166.92.235.

ip4rを見ましたが、 http://postgres.heroku.comを使用しているため、これをインストールするオプションがない可能性があります。サポート チームに確認のメールを送信しました。

それまでの間、その他のフィードバックをお待ちしております。

4

1 に答える 1

1

ip4r 自体がマッチングに役立つ可能性は低いです。ip4r は、たとえば、格納された CIDR ブロックが重複できないという制約を適用するなど、サブネットの GIN インデックスが必要な場合に最も必要です。

2 つのオプションがあります。最初の最良の方法は、PostgreSQL の inet タイプを使用し、ipv4 アドレスをタイプ inet に格納することです。次に、標準のテキスト表現を使用します。たとえば、次のように比較します。

select '10.59.3.1'::text > '101.3.4.1';
 ?column? 
----------
 t
(1 row)

select '10.59.3.1'::inet > '101.3.4.1';
 ?column? 
----------
 f
(1 row)

このタイプは標準の PostgreSQL に含まれているため、アドオンは必要ありません。

2 番目のオプションは、次のように int(inet) 関数を作成することです。

CREATE OR REPLACE FUNCTION to_int(inet) RETURNS bigint LANGUAGE SQL IMMUTABLE AS $$
SELECT $1 - '0.0.0.0';
$$;

それで

select to_int('10.0.0.1');
  to_int   
-----------
 167772161
(1 row)

このようにして、データベースで ipv4 を int に変換できます。

ただし、inet タイプをお勧めします。彼らは本当に役に立ちます。ほとんどのユースケースでは ip4r は必要ありません。

于 2013-04-01T09:46:50.533 に答える