Home  //  Play

Manticore Geosearch Example

Difficulty: Beginner
Estimated Time: 5 minutes

Manticoresearch - Manticore Geosearch example

In this tutorial you will learn how to perform geosearches in Manticore Search.

The enviroment will launch a small docker instance with Manticore Search installed a small Real-Time index containing data from geonames.org.

This course is based on the PHP Geo Example which can be found at https://github.com/adriannuta/SphinxGeoExample .

Manticore Geosearch Example

Step 1 of 4

Step 1

Setup

Wait until the docker image is launched. For simplicity you will be logged directly in the docker environment.

Connecting to Manticore

Let's connect to Manticore using the MySQL client:

mysql -P9306 -h0

The geodemo index

First, let's look at the index structure

DESC geodemo;

The index contains the geo coordinates in both radians and degrees, as well as several properties like the name of the location, country and state code.

SELECT * FROM geodemo;

Step 2

GEODIST

Manticore provides function GEODIST which can be used to calculate distance between 2 geocoordinates

GEODIST(lat1, lon1, lat2, lon2, { option=value, ... })

The first 4 parameters are the geocoordinate pairs. The last parameter uses a simple format similar to JSON to define several options for the GEODIST function:

  • in - defines the input unit of measure. Coordinates can be in degrees (degrees or deg) or radians (radians or rad). Both geocoordinate pairs must use same unit of measure
  • out - defines the output unit of measure. The distance can be expressed in meters (meters or m), kilometers (kilometers or km), feets (feet or ft) or miles (miles or mi)
  • method - defines the algorithm used. 2 values can be used here: adaptive and haversine. haversine was the first algorithm used. Adaptive is the default algorithm used and it's more faster and precise than haversine. We recommend leaving the default method.

GEODIST will provide a measured distance and it's result can be used to sort the query result. A typical query will look like:

SELECT *,GEODIST(latitude_deg,longitude_deb, 34.606,-2.799,{in=deg,out=km}) as distance FROM geodemo ORDER BY distance ASC;

Step 3

Performing queries

Let's start first with a regular text search. In this case we will search for stadiums

SELECT * FROM geodemo WHERE MATCH('Stadium');

Now let's add a location and see the closest stadiums next to it:

SELECT name,GEODIST(latitude_deg,longitude_deg,51.5073907,-0.1276999,{in=deg,out=km}) as distance FROM geodemo WHERE MATCH('Stadium') ORDER BY distance ASC;

In this case the distance is expressed in kilometers. If we want to use imperial system, we can switch to miles:

SELECT name,GEODIST(latitude_deg,longitude_deg,51.5073907,-0.1276999,{in=deg,out=miles}) as distance FROM geodemo WHERE MATCH('Stadium') ORDER BY distance ASC;

Step 4

Filtering by distance.

The distance can also be used to filter out the results.

In the previous example we sorted only by the distance. But if we are doing full-text searches we would want the text scoring to have priority and limit the results to a close area from our location.

Let's take this example:

SELECT name,GEODIST(latitude_deg,longitude_deg,51.5073907,-0.1276999,{in=deg,out=miles}) as distance,WEIGHT() FROM geodemo WHERE MATCH('hotel MAYBE club') ORDER BY WEIGHT() DESC;

If we sort by score, in the top results we will get places that are far away from us. Doing the other way around, will give us closests locations, but not all will have a top text score:

SELECT name,GEODIST(latitude_deg,longitude_deg,51.5073907,-0.1276999,{in=deg,out=miles}) as distance,WEIGHT() FROM geodemo WHERE MATCH('hotel MAYBE club') ORDER BY DISTANCE ASC;

The solution is to limit our search results, let's say 10 miles and sort first by text score and secondly by distance:

SELECT name,GEODIST(latitude_deg,longitude_deg,51.5073907,-0.1276999,{in=deg,out=miles}) as distance,WEIGHT() FROM geodemo WHERE MATCH('hotel MAYBE club') AND distance < 10 ORDER BY WEIGHT() DESC, DISTANCE ASC;