Archive for 12月 2013

こんにちは、Curious Vehicle中鉢です。

本日、弊社サービスのCLOUDSOLR上に
位置情報検索紹介用のページを作成しました。
Solrのみではなかなか視覚的にわかりづらいため、
位置情報をGoogle MapのAPIを利用して地図上にプロットし
視覚的に位置情報検索をわかりやすくしてあります。
ぜひ一度位置情報検索がどのようなものかご覧になってみてください。

https://solr.jp/map

さて、本日は上記の位置情報検索紹介用ページで利用されている
SolrのSpartial Searchという機能の説明をさせていただこうと思います。

Solrにはspartial searchという位置情報を検索するための機能があり、
その機能を使うことで

特定の地点から一定の距離の範囲内にある位置情報検索する。

といった位置情報を利用した機能を実装することができるようになります。

それでは、solr側でどういう設定をして、どういったデータをインデキシングし、
クライアント側からはどう検索できるのか、というのを順を追って説明していきます。

  1. schema.xmlの設定
    まずはSolr側の設定です。
    これはSolrのexample/solr/collection1/conf/schema.xmlの設定を
    そのまま利用しますので、すでに定義されている場合は
    飛ばしてしまってかまいません。

    <!-- locatoinというfieldTypeと
     *_p、*_coodinateというdynamicFieldを設定します -->
    <!-- example/solr/collection1/conf/schema.xml には
    すでに定義されているので、そこから変えていなければ
    追加する必要はありません。 -->
    
    <!-- A specialized field for geospatial search. If indexed, this fieldType must not be multivalued. -->
    <fieldType name="location"
     subFieldSuffix="_coordinate"/>
    
    <!-- Type used to index the lat and lon components for the "location" FieldType -->
    <dynamicField name="*_coordinate"
     type="tdouble"
     indexed="true"
     stored="false" />
    ・
    ・
    ・
    <dynamicField name="*_p"
     type="location"
     indexed="true"
     stored="true"/>
    
  2. データのインデキシング
    次に「*_p」のダイナミックフィールドに対して緯度経度のデータを
    投入します。ここでは「point_p」というフィールドに対して
    東京駅、有楽町駅、銀座一丁目駅、京橋駅、大手町駅の
    緯度経度データをインデキシングしています。以下のinput.xmlを新たに作成し、
    その下のcurlコマンドでインデキシングしましょう。input.xml

    <add>
      <doc>
        <field name="id">東京駅</field>
        <field name="point_p">35.680777,139.766969</field>
      </doc>
      <doc>
         <field name="id">有楽町駅</field>
         <field name="point_p">35.67506,139.763312</field>
      </doc>
      <doc>
        <field name="id">銀座一丁目駅</field>
        <field name="point_p">35.674529,139.766777</field>
      </doc>
      <doc>
        <field name="id">京橋駅</field>
        <field name="point_p">35.676664,139.770092</field>
      </doc>
      <doc>
        <field name="id">大手町</field>
        <field name="point_p">35.684786,139.766065</field>
      </doc>
    </add>
    

    curlでインデキシング

     $ curl "http://localhost:8983/solr/collection1/upadte?commit=true" --data-binary @input.xml -H 'Content-type: text/xml; charset=utf-8'
    
  3. 検索方法
    最後にクライアント側からインデキシングされたデータを検索します。
    今回は東京駅から1km圏内の位置情報を検索するというクエリを投げてみます。

    http://localhost:8983/solr/collection1/select?q=*:*&fq=%7B!geofilt%20sfield%3Dpoint_p%7D&pt=35.68096041340794,139.76710081100464&d=1 

    上手くいくと5件データがヒットするはずです。
    渡されたパラメータについて詳しく見ていくと以下のようになっています。

      q  *:* インデキシングされた全件検索を指定
      fq  {!geofilt sfield:point_p} 距離によるフィルタ、フィールドはpoint_pを使用
      pt  35.680??,139.767?? 検索の基準となる位置情報、緯度、経度をカンマ区切りで指定。
      d  1 検索の基準となるptパラメータの位置からこのパラメータに与えられた数値km範囲内の位置情報を検索

上記のようにSolrからは
非常に簡単に位置情報の検索ができるようになっています。
自社で位置情報をたくさん持っているというところがあれば
面白いサービスを提供できるかもしれません。

 

それではまた!

 

【12/10】 追記

位置情報検索を実施する上で設定が必要なフィールドが足りなかったため、「*_coordinate」のダイナミックフィールドの記述を追記しました。