Backendless Support
 

Partial match geopoint search

Backendless Service Platform supports multiple ways to perform a geopoint search. The search may be accomplished in radius, a rectangular area and there is a search with an SQL query. 

Additionally, there is a way to search on partial metadata match. This type of search can be combined with all other aforementioned search types. A partial match search will return geopoints whose metadata matches the values specified in the query for the specified (or greater) number of percent. 

Consider the sample geodata from the article How to import geo data from a CSV file. The imported data is rendered as shown below in Backendless console:

Suppose each geopoint represents a profile of a person with interests and food preferences. Each geopoint contains the following metadata properties: burgers, hiking, chinese, gender and city, with the first three containing the values of yes or no. Suppose a search needs to find all the geopoints that have a 30% match for the following key/value pairs: burgers=yes, hiking=yes and/or chinese=yes. In others words it does not matter which properties match as long as one third of them have the specified values (one third is roughly 30%). 

Consider the following code:

Asynchronous sample (Android and Plain Java):
BackendlessGeoQuery query = new BackendlessGeoQuery();
query.addCategory( "personals" );
query.setIncludeMeta( true );
query.putRelativeFindMetadata( "burgers", "true" );
query.putRelativeFindMetadata( "hiking", "true" );
query.putRelativeFindMetadata( "chinese", "true" );
query.setRelativeFindPercentThreshold( 30.0 );
AsyncCallback<BackendlessCollection<SearchMatchesResult>> relativeFindCallback = new AsyncCallback<BackendlessCollection<SearchMatchesResult>>()
{
 @Override
 public void handleResponse( BackendlessCollection<SearchMatchesResult> searchMatchesCollection )
 {
 Iterator<SearchMatchesResult> iterator = searchMatchesCollection.getCurrentPage().iterator();
 while( iterator.hasNext() )
 {
 SearchMatchesResult result = iterator.next();
 System.out.println( "MATCH: %" + result.getMatches() );
 System.out.println( result.getGeoPoint() );
 System.out.println( "================================" );
 }
 }
 @Override
 public void handleFault( BackendlessFault backendlessFault )
 {
 System.out.println( "Server reported an error - " + backendlessFault.getMessage() );
 }
};
Backendless.Geo.relativeFind( query, relativeFindCallback );
Synchronous sample (Plain Java only):
BackendlessGeoQuery query = new BackendlessGeoQuery();
query.addCategory( "personals" );
query.setIncludeMeta( true );
query.putRelativeFindMetadata( "burgers", "true" );
query.putRelativeFindMetadata( "hiking", "true" );
query.putRelativeFindMetadata( "chinese", "true" );
query.setRelativeFindPercentThreshold( 30.0 );
BackendlessCollection<SearchMatchesResult> searchMatchesCollection;
searchMatchesCollection = Backendless.Geo.relativeFind( query );
Iterator<SearchMatchesResult> iterator = searchMatchesCollection.getCurrentPage().iterator();
while( iterator.hasNext() )
{
 SearchMatchesResult result = iterator.next();
 System.out.println( "MATCH: " + result.getMatches() + "%" );
 System.out.println( result.getGeoPoint() );
 System.out.println( "================================" );
}
The program output is:
MATCH: 66.6667%
GeoPoint{objectId='86EB3C30-A4C0-A46E-FF4B-BE9678647000', latitude=29.76328, longitude=-95.36327, categories=[personals], metadata={burgers=true, gender=male, hiking=false, chinese=true, city=Houston}, distance=null}
================================
MATCH: 66.6667%
GeoPoint{objectId='A1A35837-E30B-419A-FF5E-1C9C30E0C100', latitude=32.78306, longitude=-96.80667, categories=[personals], metadata={gender=female, burgers=true, hiking=true, chinese=false, city=Dallas}, distance=null}
================================
MATCH: 33.3333%
GeoPoint{objectId='4745949A-8941-9DCC-FFAB-9D068CFF0100', latitude=33.15067, longitude=-96.82361, categories=[personals], metadata={gender=female, burgers=false, chinese=true, hiking=false, city=Frisco}, distance=null}
================================
MATCH: 33.3333%
GeoPoint{objectId='CC5ECD9F-7A8F-7A9B-FF44-6CC19569CC00', latitude=33.01984, longitude=-96.69889, categories=[personals], metadata={gender=male, burgers=false, chinese=false, hiking=true, city=Plano}, distance=null}
================================

As it can be noticed the search accomplished exactly what it has been aimed at - a partial match at or greater than the percentage threshold. 

NOTICE: the search results are returned through a collection of the SearchMatchesResult objects. 

Each object contains a geopoint and the percentage of matches for the geopoint's metadata against the requested key/value properties.

Review related topic:

Is article helpful?