-
Notifications
You must be signed in to change notification settings - Fork 66
Description
Current Behavior
When moving inside the Google Maps, search results are returned based on its position.
To determine what documents should be returned, instant-meilisearch calculates the middle point of the Maps window and the distance between each corner.
It then creates a filter (see geo filter documentation based on that middle point and the distance between each corner.
_geoRadius(lat, lng, distance_in_meters)
No sorting
The first itteration of instant-meilisearch's geosearch also provided by default a sort rule whereas geo points closer to the center of the map were considered more important than other.
Which created packs of markers in the center of the map:
By removing them, the markers are more scattered, which make the maps look nicer:
But what if we want to sort?
Without providing by default the sorting feature, we still want to provide the possibility to the user to sort its markers to be as close as possible to the center.
Solution
To enable sorting from the center point of the map, the solution is to provide a parameter proximityGeoRule in the instantMeiliSearch parameters. Which would default to false.
const searchClient = instantMeiliSearch(
'https://demos.meilisearch.com',
'...',
{
proximityGeoRule: true
}
)This will enable sorting.
Here are the steps to follow to implement this feature:
1. add a proximityGeoRule in the InstantMeiliSearch Parameter
// types.ts
type ClientParams = {
primaryKey?: string
placeholderSearch?: boolean
sort?: string
indexUid: string
paginationTotalHits: number
proximityGeoRule?: boolean
}2. Add the information in the geoSearchContext
export type GeoSearchContext = {
aroundLatLng?: string
aroundLatLngViaIP?: boolean
aroundRadius?: number | 'all'
aroundPrecision?: number
minimumAroundRadius?: number
insideBoundingBox?: InsideBoundingBox
insidePolygon?: ReadonlyArray<readonly number[]>
proximityGeoRule?: boolean
}3. Use the information in the geo-rule adapter
In geo-rules-adapter.ts if proximityGeoRule is set to true, sort filter should be added:
if (proximityGeoRule) {
sort = `_geoPoint(${lat3}, ${lng3}):asc`
} else {
sort = undefined
}4. make aroundLatLng work without aroundRadius
Because aroundLatLng only provided a middle point, and not a radius, only a sort was previously done.
const sort = `_geoPoint(${lat3}, ${lng3}):asc`
Because of a lack of radius provided, we cannot create a filter is not possible.
Thus, if proximityGeoRule is set to true, the following condition should be added in geo-rules-adapter.ts
else if (middlePoint != null) {
const [lat3, lng3] = middlePoint.split(',')
const sort = `_geoPoint(${lat3}, ${lng3}):asc`
return { sort }
}5. Add the sort in the search params adapter.
In the search params adapter filter from the geosearch adapter are added in the final search requests parameters sent to MeiliSearch.
if (geoRules?.filter) { ... }The same should be added for sort:
if (geoRules?.sort) {
if (meiliSearchParams.sort) {
meiliSearchParams.sort.unshift(geoRules.sort)
} else {
meiliSearchParams.sort = [geoRules.sort]
}
}6. add tests
This behavior should be tested in geosearch.tests.ts

