This guide shows you how to filter results around a location. This location can be set manually or taken from the end user’s current position.
Dataset
The guide uses a dataset of the 3,000+ biggest airports in the world.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| [
{
"objectID": "3797",
"name": "John F Kennedy Intl",
"city": "New York",
"country": "United States",
"iata_code": "JFK",
"_geoloc": {
"lat": 40.639751,
"lng": -73.778925
},
"links_count": 911
}
]
|
Store each record’s location (latitude and longitude) in the _geoloc
attribute.
First, download the airport dataset and then import it into Algolia.
Initialize the client
1
2
3
4
5
6
7
8
9
10
11
12
| // composer autoload
require __DIR__ . '/vendor/autoload.php';
// if you are not using composer
// require_once 'path/to/algoliasearch.php';
$client = \Algolia\AlgoliaSearch\SearchClient::create(
'YourApplicationID',
'YourWriteAPIKey'
);
$index = $client->initIndex('your_index_name');
|
1
2
3
4
| require 'algolia'
client = Algolia::Search::Client.create('YourApplicationID', 'YourWriteAPIKey')
index = client.init_index('your_index_name')
|
1
2
3
4
5
6
7
8
| // Default version
import algoliasearch from 'algoliasearch';
// Search-only version
// import algoliasearch from 'algoliasearch/lite';
const client = algoliasearch('YourApplicationID', 'YourWriteAPIKey');
const index = client.initIndex('your_index_name');
|
1
2
3
4
| from algoliasearch.search_client import SearchClient
client = SearchClient.create('YourApplicationID', 'YourWriteAPIKey')
index = client.init_index('your_index_name')
|
1
2
| let client = SearchClient(appID: "YourApplicationID", apiKey: "YourWriteAPIKey")
let index = client.index(withName: "your_index_name")
|
1
2
3
4
5
6
7
| val client = ClientSearch(
applicationID = ApplicationID("YourApplicationID"),
apiKey = APIKey("YourWriteAPIKey")
)
val indexName = IndexName("your_index_name")
client.initIndex(indexName)
|
1
2
| SearchClient client = new SearchClient("YourApplicationID", "YourWriteAPIKey");
SearchIndex index = client.InitIndex("your_index_name");
|
1
2
3
4
| SearchClient client =
DefaultSearchClient.create("YourApplicationID", "YourWriteAPIKey");
SearchIndex index = client.initIndex("your_index_name");
|
1
2
3
4
5
6
7
8
| package main
import "github.com/algolia/algoliasearch-client-go/v3/algolia/search"
func main() {
client := search.NewClient("YourApplicationID", "YourWriteAPIKey")
index := client.InitIndex("your_index_name")
}
|
1
2
| // No initIndex
val client = new AlgoliaClient("YourApplicationID", "YourWriteAPIKey")
|
Even if you just want to sort by distance to a location, your textual relevance should also be good so that end users can refine the search with a query. To do that, you must configure the index.
The searchable attributes are: name
, city
, country
, and iata_code
.
1
2
3
4
5
6
7
8
9
10
11
| $index->setSettings([
'searchableAttributes' => [
'name',
'city',
'country',
'iata_code'
],
'customRanking' => [
'desc(links_count)'
]
]);
|
1
2
3
4
5
6
7
8
9
10
11
| index.set_settings(
searchableAttributes: [
'name',
'city',
'country',
'iata_code'
],
customRanking: [
'desc(links_count)'
]
)
|
1
2
3
4
5
6
7
8
9
10
11
| index.setSettings({
searchableAttributes: [
'name',
'city',
'country',
'iata_code'
],
customRanking: ['desc(links_count)'],
}).then(() => {
// done
});
|
1
2
3
4
5
6
7
8
9
10
11
| index.set_settings({
'searchableAttributes': [
'name',
'city',
'country',
'iata_code',
],
'customRanking': [
'desc(links_count)'
]
})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| let settings = [
"searchableAttributes": [
"name",
"city",
"country",
"iata_code"
],
"customRanking": [
"desc(links_count)"
]
]
index.setSettings(
settings,
completionHandler: { (content, error) -> Void in
// [...]
}
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| val settings = settings {
searchableAttributes {
+"name"
+"city"
+"country"
+"iata_code"
}
customRanking {
+Desc("links_count")
}
}
index.setSettings(settings)
|
1
2
3
4
5
6
7
8
9
10
| IndexSettings settings = new IndexSettings
{
SearchableAttributes = new List<string> { "name", "city", "country", "iata_code" },
CustomRanking = new List<string> { "desc(links_count)" }
};
index.SetSettings(setting);
// Asynchronous
await index.SetSettingsAsync(settings);
|
1
2
3
4
| index.setSettings(new IndexSettings()
.setSearchableAttributes(Arrays.asList("name", "city", "country", "iata_code"))
.setCustomRanking(Collections.singletonList("desc(links_count"))
);
|
1
2
3
4
5
6
7
8
9
| res, err := index.SetSettings(search.Settings{
SearchableAttributes: opt.SearchableAttributes(
"name",
"city",
"country",
"iata_code",
),
CustomRanking: opt.CustomRanking("desc(links_count)"),
})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| val result: Future[Task] = client.execute {
setSettings of "myIndex" `with` IndexSettings(
searchableAttributes = Some(Seq(
SearchableAttributes.attributes("name"),
SearchableAttributes.attribute("city"),
SearchableAttributes.unordered("country"),
SearchableAttributes.attribute("iata_code"),
))
customRanking = Some(Seq(
CustomRanking.desc("links_count")
))
)
}
|
Custom ranking
The engine will use an airport’s number of connected airports as a ranking metric. The more connections, the better.
Ranking
When filtering around a location, Algolia can also sort the results by distance from this location. This sorting by distance happens in the ranking formula’s geo
criterion. If geo
isn’t active, you can’t sort by distance.
Filtering around a given location
To filter airports around New York City (latitude 40.71 and longitude -74.01), use the aroundLatLng
parameter.
1
2
3
| $results = $index->search('', [
'aroundLatLng' => '40.71, -74.01'
]);
|
1
| results = index.search('', { aroundLatLng: '40.71, -74.01' })
|
1
2
3
4
5
| index.search('', {
aroundLatLng: '40.71, -74.01'
}).then(({ hits }) => {
console.log(hits);
});
|
1
2
3
| results = index.search('', {
'aroundLatLng': '40.71, -74.01',
})
|
1
2
3
4
5
6
| let query = Query(query: "")
query.aroundLatLng = LatLng(lat: 40.71, lng: -74.01)
index.search(query, completionHandler: { (res, error) in
print(res)
})
|
1
2
3
4
5
| val query = query {
aroundLatLng = Point(40.71f, -74.01f)
}
index.search(query)
|
1
2
3
4
| index.Search<T>(new Query("")
{
AroundLatLng = new List<string> { "40.71, -74.01" }
});
|
1
| index.search(new Query().setAroundLatLng("40.71, -74.01"));
|
1
| res, err := index.Search("", opt.AroundLatLng("40.71, -74.01"))
|
1
2
3
4
5
6
7
8
| client.execute {
search into "myIndex" query Query(
query = Some(""),
aroundLatLng = Some(
AroundLatLng("40.71, -74.01")
)
)
}
|
An empty query (''
) tells Algolia to retrieve all airports
Filtering around the end user’s current location
As you don’t know the end user’s coordinates in advance, you can retrieve their IP address’s associated location with the aroundLatLngViaIP
parameter.
1
2
3
4
5
6
7
8
9
10
11
| /**
* '94.228.178.246' should be replaced with the actual IP you would like to search around.
* Depending on your stack there are multiple ways to get this information.
*/
$ip = '94.228.178.246';
$results = $index->search('', [
'aroundLatLngViaIP' => true,
'X-Forwarded-For' => $ip
]);
|
1
2
3
4
5
6
7
8
| results = index.search('', {
aroundLatLngViaIP: true,
headers: {
# '94.228.178.246' should be replaced with the actual IP you would like to search around.
# Depending on your stack there are multiple ways to get this information.
'X-Forwarded-For': '94.228.178.246'
}
})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| /**
* '94.228.178.246' should be replaced with the actual IP you would like to search around.
* Depending on your stack there are multiple ways to get this information.
*/
index.search('', {
aroundLatLngViaIP: true,
headers: {
'X-Forwarded-For': '94.228.178.246'
}
}).then(({ hits }) => {
console.log(hits);
});
|
1
2
3
4
5
6
7
8
9
| # '94.228.178.246' should be replaced with the actual IP you would like to search around.
# Depending on your stack there are multiple ways to get this information.
ip = '94.228.178.246'
results = index.search('', {
'aroundLatLngViaIP': True,
'X-Forwarded-For': ip
})
|
1
2
3
4
5
6
7
8
9
10
11
| /// '94.228.178.246' should be replaced with the actual IP you would like to search around.
/// Depending on your stack there are multiple ways to get this information.
client.setHeader(withName: "X-Forwarded-For", to: "94.228.178.246")
let query = Query()
query.aroundLatLngViaIP = true
index.search(query, completionHandler: { (res, error) in
print(res)
})
|
1
2
3
4
5
6
7
8
9
10
| /**
* '94.228.178.246' should be replaced with the actual IP you would like to search around.
* Depending on your stack there are multiple ways to get this information.
*/
val query = query {
aroundLatLngViaIP = true
}
index.search(query, requestOptions { headerForwardedFor("94.228.178.246") })
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // '94.228.178.246' should be replaced with the actual IP you would like to search around.
// Depending on your stack there are multiple ways to get this information.
var configuration = new SearchConfig("YourApplicationID", "YourWriteAPIKey")
{
DefaultHeaders = new Dictionary<string, string> { { "X-Forwarded-For", "94.228.178.246" } }
};
SearchClient client = new SearchClient(configuration);
index.Search<T>(new Query("")
{
AroundLatLngViaIP = true
});
|
1
2
3
4
5
6
7
8
9
| // '94.228.178.246' should be replaced with the actual IP you would like to search around.
// Depending on your stack there are multiple ways to get this information.
index.search(
new Query()
.setAroundLatLngViaIP(true),
new RequestOptions()
.addExtraHeader("X-Forwarded-For", "94.228.178.246")
);
|
1
2
3
4
5
6
7
8
| // "94.228.178.246" should be replaced with the actual IP you would like to search around.
// Depending on your stack there are multiple ways to get this information.
extraHeaders := opt.ExtraHeaders(map[string]string{
"X-Forwarded-For": "94.228.178.246",
})
res, err := index.Search("", opt.AroundLatLngViaIP(true), extraHeaders)
|
1
2
3
4
5
6
7
8
9
10
11
| // '94.228.178.246' should be replaced with the actual IP you would like to search around.
// Depending on your stack there are multiple ways to get this information.
client.execute {
search into "myIndex" query Query(
query = Some(""),
aroundLatLngViaIP = Some(true)
) options RequestsOptions(
extraHeaders = Some(Map("X-Forwarded-For" -> "94.228.178.246"))
)
}
|
Filtering by radius
By default, the engine automatically defines a radius to filter on depending on the population density of the end user’s location.
To define the radius yourself, use the aroundRadius
parameter. The bigger the radius, the less filtering you have.
This example sorts by distance to New York City, with a radius of 1,000 km.
1
2
3
4
| $results = $index->search('', [
'aroundLatLng' => '40.71, -74.01'
'aroundRadius' => 1000000 // 1,000 km
]);
|
1
2
3
4
| results = index.search('', {
aroundLatLng: '40.71, -74.01',
aroundRadius: 1000000 # 1,000 km
})
|
1
2
3
4
5
6
| index.search('', {
aroundLatLng: '40.71, -74.01',
aroundRadius: 1000000 // 1,000 km
}).then(({ hits }) => {
console.log(hits);
});
|
1
2
3
4
| results = index.search('', {
'aroundLatLng': '40.71, -74.01',
'aroundRadius': 1_000_000 # 1,000 km
})
|
1
2
3
4
5
6
7
| let query = Query(query: "")
query.aroundLatLng = LatLng(lat: 40.71, lng: -74.01)
query.aroundRadius = .explicit(1000000) // 1,000 km
index.search(query, completionHandler: { (res, error) in
print(res)
})
|
1
2
3
4
5
6
| val query = query {
aroundLatLng = Point(40.71f, -74.01f)
aroundRadius = AroundRadius.InMeters(1000000) // 1,000 km
}
index.search(query)
|
1
2
3
4
5
| index.Search<T>(new Query("")
{
AroundLatLng = new List<string> { "40.71, -74.01" },
AroundRadius = 1000000 // 1,000 km
});
|
1
2
3
4
| index.search(new Query()
.setAroundLatLng("40.71, -74.01")
.setAroundRadius(AroundRadius.of(1000000)) // 1,000 km
);
|
1
2
3
4
5
| res, err := index.Search(
"",
opt.AroundLatLng("40.71, -74.01"),
opt.AroundRadius(1000000), // 1,000 km
)
|
1
2
3
4
5
6
7
8
9
10
11
| client.execute {
search into "myIndex" query Query(
query = Some(""),
aroundLatLng = Some(
AroundLatLng("40.71, -74.01")
),
aroundRadius = Some(
AroundRadius.integer(1000000)
) // 1,000 km
)
}
|