We used cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it. What For?

Liferay SOLR GeoSpatial Search

Sometimes you may want to implement GeoSpatial Search in your liferay portal. Solr supports location data for use in spatial/geospatial searches using which we can implement GeoSpatial Search. Using spatial search you can,

 

  1. Represent spatial data in the index

  2. Filter by some spatial concept such as a bounding box or other shape

  3. Sort by distance

  4. Score/boost by distance

 

Prerequisite :


SOLR integration with Liferay, Knowledge of search using SOLR in Liferay, Basic idea of GeoSpatial search.


You can visit SOLR Documentation of spatial search for detailed information.


Below are the steps to implement GeoSpatial search with SOLR in Liferay. I am assuming you have already integrated SOLR with Liferay. I am using SOLR 4.10.2 and Liferay 6.2 CE GA4.


For this example I have created one entity named “Foo” in which I will be storing location data. I have created “FooIndexer.java” to index Foo entities in SOLR from Liferay (https://help.liferay.com/hc/en-us/articles/360018179251-Implementing-Search-and-Indexing).

 

Following are the steps to implement GeoSpatial Search in Liferay using SOLR


  1. Make changes in schema.xml for location data

 

You need to add following lines in “schema.xml” file of SOLR for location data.

 

 

<!-- Location Field Type for Geo Search -->

<fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>


<field indexed="true" name="foo_latitude_longitude" multiValued="false" stored="true" type="text" />

<field indexed="true" name="foo_latlon" multiValued="false" type="location"  stored="true" />


<dynamicField name="*_coordinate" type="double" indexed="true" stored="true" multiValued="false"/>


<copyField source="foo_latitude_longitude" dest="foo_latlon"/>

 

 

2) Make changes in FooIndexer.java  to index location data

 

Now you need to add following lines in doGetDocument(Object obj) method of FooIndexer class which will add location data in “longitude,latitude” format. You can use Google or any other suitable API to get location data as per your requirements.

 
document.addText("foo_latitude_longitude", foo.getLatitude()+","+foo.getLongitude());
 
Once Foo entity is indexed location data will be added for GeoSpatial Search.
 
3) Search location data using SOLR from LR

You can now use following sample code to get search results from location data.

 

 

Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(Foo.class);

ArrayList<BooleanClause> booleanClauses = new ArrayList<BooleanClause>();

HttpServletRequest httpRequest = PortalUtil.getHttpServletRequest(resourceRequest);

ThemeDisplay themeDisplay = (ThemeDisplay)resourceRequest.getAttribute(

WebKeys.THEME_DISPLAY);

Group group = GroupLocalServiceUtil.getGroup(themeDisplay.getCompanyId(), “group-name”);


SearchContext searchContext = SearchContextFactory.getInstance(httpRequest);

searchContext.setCompanyId(themeDisplay.getCompanyId());

searchContext.setGroupIds(new long[]{group.getGroupId()});


String latLong = “36.9923139,-122.0581762” // location point

int distance = 50; // Distance in KM


String geoSearchQuery = "{!geofilt pt="+latLong+" sfield=foo_latlon d="+distance+"}";

TermQuery termQuery = TermQueryFactoryUtil.create(searchContext, "_query_", geoSearchQuery);

BooleanClause geoSearchBooleanClause = BooleanClauseFactoryUtil.create(searchContext, termQuery, BooleanClauseOccur.MUST.getName());

booleanClauses.add(geoSearchBooleanClause);


searchContext.setBooleanClauses(booleanClauses.toArray(new BooleanClause[booleanClauses.size()]));

Hits results = indexer.search(searchContext);

 

Using above code you can get all foo entities having location data in radius of 50 km from “36.9923139,-122.0581762” point.


Have a great day ahead !!!

contact-us Request a callback WhatsApp