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,

Represent spatial data in the index Filter by some spatial concept such as a bounding box or other shape Sort by distance 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://dev.liferay.com/develop/tutorials/-/knowledge_base/6-2/implementing-search-and-indexing).

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

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 !!!

For professional paid support, you may contact us at [email protected] .