One of my projects required a spatial search using geonames to match cities across multiple local data sources. We had few options to do this instead of deploying our own geo mapping service such as geonames webservice. However our product use cases required relevancy tuning and boosting of certain geonames place types, so we decided to setup Solr.
To setup Solr 4.x for spatial search, I followed the instructions at http://wiki.apache.org/solr/SolrAdaptersForLuceneSpatial4, but still ran into issues. This is consolidation of information collected from various forums to setup spatial search on Solr 4.3 successfully.
The following changes are done to make my Solr 4.x installation:
Schema definition for geonames:
<field name="id" type="string" indexed="true" stored="true" required="true" />
<field name="basic_name" type="text_general" indexed="true" stored="true" required="true" omitNorms="false" />
<field name="utf8_name" type="text_general" indexed="true" stored="true" />
<field name="latitude" type="double" indexed="true" stored="true" />
<field name="longitude" type="double" indexed="true" stored="true" />
<field name="feature_class" type="string" indexed="true" stored="true" />
<field name="feature_code" type="string" indexed="true" stored="true" />
<field name="country_code" type="string" indexed="true" stored="true" />
<field name="population" type="long" indexed="true" stored="true" />
<field name="elevation" type="int" indexed="true" stored="true" />
<field name="gtopo30" type="int" indexed="true" stored="true" />
<field name="timezone" type="string" indexed="true" stored="true" />
<field name="date_modified" type="date" indexed="true" stored="true" />
<field name="latlon" type="location_rpt" indexed="true" stored="true"/>
......
<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
spatialContextFactory="com.spatial4j.core.context.jts.JtsSpatialContextFactory"
distErrPct="0.025"
maxDistErr="0.000009"
units="degrees"
/>
......
Geonames database
To setup geonames, download the database (allcountries.txt) and import into the Solr.
Testing the setup
Start the server.
Fire the query: http://localhost:8983/solr/collection1/select/?fl=*,score&sort=score%20asc&q={!geofilt%20score=distance%20filter=true%20sfield=latlon%20pt=42.56667,1.48333%20d=1}&fq=feature_code:PPL
Note: The query includes 'score=distance' and 'sort=score' to include distance in the response.
Query Response
To setup Solr 4.x for spatial search, I followed the instructions at http://wiki.apache.org/solr/SolrAdaptersForLuceneSpatial4, but still ran into issues. This is consolidation of information collected from various forums to setup spatial search on Solr 4.3 successfully.
The following changes are done to make my Solr 4.x installation:
- SOLR2155 is only for Solr 3.x and it doesnt work on 4.3. Solr 4.x supports alternative geospatial method. So disable the following in the solrconfig.xml.
- <queryParser name="gh_geofilt" class="solr2155.solr.search.SpatialGeoHashFilterQParser$Plugin" />
- <valueSourceParser name="geodist" class="solr2155.solr.search.function.distance.HaversineConstFunction$HaversineValueSourceParser" />
- If you have this enabled in Solr 4.x and used 3.x types, you should see the following error
- Unable to create core: collection1 org.apache.solr.common.SolrException: org/apache/lucene/queryParser/ParseException
- Download jts-1.8.jar into solr-webapp/webapp/WEB-INF/lib
- http://www.jarvana.com/jarvana/archive-details/com/vividsolutions/jts/1.8/jts-1.8.jar
- Without this, you would get the following error:
- ERROR org.apache.solr.core.CoreContainer – null:java.lang.NoClassDefFoundError: com/vividsolutions/jts/geom/Geometry
- If you are planning to import data from mysql, download the mysql connector into solr-webapp/webapp/WEB-INF/lib
- mysql-connector-java-5.1.25.tar.gz
Schema definition for geonames:
<field name="id" type="string" indexed="true" stored="true" required="true" />
<field name="basic_name" type="text_general" indexed="true" stored="true" required="true" omitNorms="false" />
<field name="utf8_name" type="text_general" indexed="true" stored="true" />
<field name="latitude" type="double" indexed="true" stored="true" />
<field name="longitude" type="double" indexed="true" stored="true" />
<field name="feature_class" type="string" indexed="true" stored="true" />
<field name="feature_code" type="string" indexed="true" stored="true" />
<field name="country_code" type="string" indexed="true" stored="true" />
<field name="population" type="long" indexed="true" stored="true" />
<field name="elevation" type="int" indexed="true" stored="true" />
<field name="gtopo30" type="int" indexed="true" stored="true" />
<field name="timezone" type="string" indexed="true" stored="true" />
<field name="date_modified" type="date" indexed="true" stored="true" />
<field name="latlon" type="location_rpt" indexed="true" stored="true"/>
......
<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
spatialContextFactory="com.spatial4j.core.context.jts.JtsSpatialContextFactory"
distErrPct="0.025"
maxDistErr="0.000009"
units="degrees"
/>
......
Geonames database
To setup geonames, download the database (allcountries.txt) and import into the Solr.
Testing the setup
Start the server.
Fire the query: http://localhost:8983/solr/collection1/select/?fl=*,score&sort=score%20asc&q={!geofilt%20score=distance%20filter=true%20sfield=latlon%20pt=42.56667,1.48333%20d=1}&fq=feature_code:PPL
Note: The query includes 'score=distance' and 'sort=score' to include distance in the response.
Query Response
<response>
</response>
No comments :
Post a Comment