Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,11 @@ geosearch_guide_filter_usage_3: |-
-X POST 'MEILISEARCH_URL/indexes/restaurants/search' \
-H 'Content-type:application/json' \
--data-binary '{ "filter": "_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])" }'
geosearch_guide_filter_usage_4: |-
curl \
-X POST 'MEILISEARCH_URL/indexes/restaurants/search' \
-H 'Content-type:application/json' \
--data-binary '{ "filter": "_geoPolygon([45.494181, 9.214024], [45.449484, 9.179175], [45.449486, 9.179177])" }'
geosearch_guide_sort_settings_1: |-
curl \
-X PUT 'MEILISEARCH_URL/indexes/restaurants/settings/sortable-attributes' \
Expand Down
69 changes: 57 additions & 12 deletions learn/filtering_and_sorting/geosearch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ Due to Meilisearch allowing malformed `_geo` fields in the following versions (v

## Preparing documents for location-based search

In order to start filtering and sorting documents based on their geographic location, you must make sure they contain a valid `_geo` field.
To start filtering documents based on their geographic location, you must make sure they contain a valid `_geo` or `_geojson` field. If you also want to sort documents geogeraphically, they must have a valid `_geo` field.

`_geo` is a reserved field. If you include it in your documents, Meilisearch expects its value to conform to a specific format.
`_geo` and `_geojson` are reserved fields. If you include one of them in your documents, Meilisearch expects its value to conform to a specific format.

When using JSON and NDJSON, `_geo` must contain an object with two keys: `lat` and `lng`. Both fields must contain either a floating point number or a string indicating, respectively, latitude and longitude:

Expand All @@ -37,6 +37,37 @@ When using JSON and NDJSON, `_geo` must contain an object with two keys: `lat` a
}
```

`_geojson` must be an object whose contents follow the [GeoJSON specification](https://geojson.org/):

```json
{
"_geojson": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0.0, 0.0]
}
}
}
```

Meilisearch does not support transmeridian shapes. If your document includes a transmeridian shape, split it into two separate shapes grouped as a `MultiPolygon` or `MultiLine`. Transmeridian shapes are polygons or lines that cross the 180th meridian.

**Meilisearch does not support polygons with holes**. If your polygon consists of an external ring and an inner empty space, Meilisearch ignores the hole and treats the polygon as a solid shape.

<Note>
### Using `_geo` and `_geojson` together

If your application requires both sorting by distance to a point and filtering by shapes other than a circle or a rectangle, you will need to add both `_geo` and `_geojson` to your documents.

When handling documents with both fields, Meilisearch:

- Ignores `_geojson` values when sorting
- Ignores `_geo` values when filtering with `_geoPolygon`
- Matches both `_geo` and `_geojson` values when filtering with `_geoRadius` and `_geoBoundingBox`
</Note>

### Examples

Suppose we have a JSON array containing a few restaurants:
Expand Down Expand Up @@ -67,7 +98,7 @@ Suppose we have a JSON array containing a few restaurants:
]
```

Our restaurant dataset looks like this once we add geopositioning data:
Our restaurant dataset looks like this once we add `_geo` data:

```json
[
Expand Down Expand Up @@ -122,13 +153,15 @@ If your dataset is formatted as CSV, the file header must have a `_geo` column.
"3","Artico Gelateria Tradizionale","Via Dogana, 1, 20123 Milan, Italy","ice cream",10,"48.8826517,2.3352748"
```

## Filtering results with `_geoRadius` and `_geoBoundingBox`
CSV files do not support the `_geojson` attribute.

## Filtering results with `_geoRadius`, `_geoBoundingBox`, and `_geoPolygon`

You can use `_geo` data to filter queries so you only receive results located within a given geographic area.
You can use `_geo` and `_geojson` data to filter queries so you only receive results located within a given geographic area.

### Configuration

In order to filter results based on their location, you must add the `_geo` attribute to the `filterableAttributes` list:
To filter results based on their location, you must add `_geo` or `_geojson` to the `filterableAttributes` list:

<CodeSamplesGeosearchGuideFilterSettings1 />

Expand All @@ -138,18 +171,24 @@ Meilisearch will rebuild your index whenever you update `filterableAttributes`.

### Usage

Use the [`filter` search parameter](/reference/api/search#filter) along with `_geoRadius` or `_geoBoundingBox`. These are special filter rules that ensure Meilisearch only returns results located within a specific geographic area.
Use the [`filter` search parameter](/reference/api/search#filter) along with `_geoRadius` and `_geoBoundingBox`. These are special filter rules that ensure Meilisearch only returns results located within a specific geographic area. If you are using GeoJSON for your documents, you may also filter results with `_geoPolygon`.

### `_geoRadius`

```
_geoRadius(lat, lng, distance_in_meters)
_geoRadius(lat, lng, distance_in_meters, resolution)
```

### `_geoBoundingBox`

```
_geoBoundingBox([{lat}, {lng}], [{lat}, {lng}])
_geoBoundingBox([LAT, LNG], [LAT, LNG])
```

### `_geoPolygon`

```
_geoPolygon([LAT, LNG], [LAT, LNG], [LAT, LNG], …)
```

### Examples
Expand All @@ -162,6 +201,10 @@ We also make a similar query using `_geoBoundingBox`:

<CodeSamplesGeosearchGuideFilterUsage3 />

And with `_geoPolygon`:

<CodeSamplesGeosearchGuideFilterUsage4 />

```json
[
{
Expand Down Expand Up @@ -189,7 +232,7 @@ We also make a similar query using `_geoBoundingBox`:
]
```

It is also possible to combine `_geoRadius` and `_geoBoundingBox` with other filters. We can narrow down our previous search so it only includes pizzerias:
It is also possible to combine `_geoRadius`, `_geoBoundingBox`, and `_geoPolygon` with other filters. We can narrow down our previous search so it only includes pizzerias:

<CodeSamplesGeosearchGuideFilterUsage2 />

Expand Down Expand Up @@ -217,11 +260,13 @@ It is also possible to combine `_geoRadius` and `_geoBoundingBox` with other fil

### Configuration

Before using geosearch for sorting, you must add the `_geo` attribute to the `sortableAttributes` list:
Before using geosearch for sorting, you must add the `_geo` attribute to the [`sortableAttributes` list](/learn/filtering_and_sorting/sort_search_results):

<CodeSamplesGeosearchGuideSortSettings1 />

[Read more about `sortableAttributes` here.](/learn/filtering_and_sorting/sort_search_results)
<Danger>
It is not possible to sort documents based on the `_geojson` attribute.
</Danger>

### Usage

Expand Down
40 changes: 31 additions & 9 deletions reference/api/search.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -481,20 +481,23 @@ You can then use the filter in a search query:

<CodeSamplesFacetedSearchWalkthroughFilter1 />

#### Filtering results with `_geoRadius` and `_geoBoundingBox`
#### Filtering results with `_geoRadius`, `_geoBoundingBox`, and `_geoPolygon`

If your documents contain `_geo` data, you can use the `_geoRadius` and `_geoBoundingBox` built-in filter rules to filter results according to their geographic position.
If your documents contain `_geo` or `_geojson` data, you can use the following built-in filter rules to filter results according to their geographic position:

<Tabs>

<Tab title="_geoRadius">
`_geoRadius` establishes a circular area based on a central point and a radius. This filter rule requires three parameters: `lat`, `lng` and `distance_in_meters`.
`_geoRadius` establishes a circular area based on a central point and a radius. This filter rule accepts the following parameters: `lat`, `lng`, `distance_in_meters`, `resolution`.

```json
_geoRadius(lat, lng, distance_in_meters)
_geoRadius(lat, lng, distance_in_meters, resolution)
```

`lat` and `lng` should be geographic coordinates expressed as floating point numbers. `distance_in_meters` indicates the radius of the area within which you want your results and should be an integer.
- `lat` and `lng` should be geographic coordinates expressed as floating point numbers.
- `distance_in_meters` indicates the radius of the area within which you want your results and should be an integer.
- `resolution` must be an integer between `3` and `1000` inclusive, and is an optional parameter. When using `_geojson` coordinates, `resolution` sets how many points Meilisearch will use to create a polygon that approximates the shape of a circle. Documents using `_geo` data ignore this parameter. Defaults to `125`. Increasing `resolution` may result in performance issues and is only necessary when dealing with large country-sized circles.


<CodeSamplesGeosearchGuideFilterUsage1 />

Expand All @@ -504,17 +507,34 @@ _geoRadius(lat, lng, distance_in_meters)
`_geoBoundingBox` establishes a rectangular area based on the coordinates for its top right and bottom left corners. This filter rule requires two arrays of geographic coordinates:

```
_geoBoundingBox([{lat}, {lng}], [{lat}, {lng}])
_geoBoundingBox([LAT, LNG], [LAT, LNG])
```

`lat` and `lng` should be geographic coordinates expressed as floating point numbers. The first array indicates the top right corner and the second array indicates the bottom left corner of the bounding box.
`LAT` and `LNG` should be geographic coordinates expressed as floating point numbers. The first array indicates the top right corner and the second array indicates the bottom left corner of the bounding box.

<CodeSamplesGeosearchGuideFilterUsage3 />

Meilisearch will throw an error if the top right corner is under the bottom left corner.

</Tab>

<Tab title="_geoPolygon">
`_geoPolygon` establishes an area based on the coordinates of the specified points. This filter rule requires three arrays or more arrays of geographic coordinates and can only be used with GeoJSON documents:

```
_geoPolygon([LAT, LNG], [LAT, LNG], [LAT, LNG], …)
```

`LAT` and `LNG` should be geographic coordinates expressed as floating point numbers. If your polygon is not closed, Meilisearch will close it automatically. Closed polygons are polygons where the first and last points share the same coordinates.

<CodeSamplesGeosearchGuideFilterUsage4 />

Polygons cannot cross the 180th meridian. If a shape crosses the antimeridian, you must make two polygons and join them using the `AND` filter operator.

`_geoPolygon` is not compatible with documents using only `_geo` data. You must specify a `_geojson` attribute to use `_geoPolygon`.

</Tab>

</Tabs>

If any parameters are invalid or missing, Meilisearch returns an [`invalid_search_filter`](/reference/errors/error_codes#invalid_search_filter) error.
Expand Down Expand Up @@ -924,7 +944,7 @@ You can search for science fiction books ordered from cheapest to most expensive

#### Sorting results with `_geoPoint`

When dealing with documents containing geolocation data, you can use `_geoPoint` to sort results based on their distance from a specific geographic location.
When dealing with documents containing `_geo` data, you can use `_geoPoint` to sort results based on their distance from a specific geographic location.

`_geoPoint` is a sorting function that requires two floating point numbers indicating a location's latitude and longitude. You must also specify whether the sort should be ascending (`asc`) or descending (`desc`):

Expand All @@ -946,7 +966,9 @@ Queries using `_geoPoint` will always include a `geoDistance` field containing t
]
```

[You can read more about location-based sorting in our dedicated guide.](/learn/filtering_and_sorting/geosearch#sorting-results-with-_geopoint)
Geographic sorting is only compatible with documents containing `_geo` data. `_geoPoint` ignores all data in the `_geojson` object.

[You can read more about location-based sorting in the dedicated guide.](/learn/filtering_and_sorting/geosearch#sorting-results-with-_geopoint)

### Matching strategy

Expand Down
4 changes: 4 additions & 0 deletions reference/errors/error_codes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ This error occurs if:

The provided `_geo` field of one or more documents is invalid. Meilisearch expects `_geo` to be an object with two fields, `lat` and `lng`, each containing geographic coordinates expressed as a string or floating point number. Read more about `_geo` and how to troubleshoot it in [our dedicated guide](/learn/filtering_and_sorting/geosearch).

## `invalid_document_geojson_field`

The `geojson` field in one or more documents is invalid or doesn't match the [GeoJSON specification](https://datatracker.ietf.org/doc/html/rfc7946).

## `invalid_export_url`

The export target instance URL is invalid or could not be reached.
Expand Down
3 changes: 2 additions & 1 deletion snippets/samples/code_samples_facet_search_3.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ client.Index("books").FacetSearch(&meilisearch.FacetSearchRequest{
```csharp C#
var query = new SearchFacetsQuery()
{
FacetQuery = "c"
FacetQuery = "c",
ExhaustiveFacetCount: true
};
await client.Index("books").FacetSearchAsync("genres", query);
```
Expand Down
7 changes: 7 additions & 0 deletions snippets/samples/code_samples_get_vector_store_settings_1.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<CodeGroup>

```bash cURL
curl \
-X GET 'MEILISEARCH_URL/indexes/INDEX_UID/settings/vector-store'
```
</CodeGroup>
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ $client->index('movies')->addDocuments($movies);
// <dependency>
// <groupId>com.meilisearch.sdk</groupId>
// <artifactId>meilisearch-java</artifactId>
// <version>0.15.0</version>
// <version>0.16.1</version>
// <type>pom</type>
// </dependency>

// For Gradle
// Add the following line to the `dependencies` section of your `build.gradle`:
//
// implementation 'com.meilisearch.sdk:meilisearch-java:0.15.0'
// implementation 'com.meilisearch.sdk:meilisearch-java:0.16.1'

// In your .java file:
import com.meilisearch.sdk;
Expand Down Expand Up @@ -192,7 +192,7 @@ namespace Meilisearch_demo
```text Rust
// In your .toml file:
[dependencies]
meilisearch-sdk = "0.29.1"
meilisearch-sdk = "0.30.0"
# futures: because we want to block on futures
futures = "0.3"
# serde: required if you are going to use documents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ client.index('books').update(primary_key: 'title')
```

```go Go
client.Index("books").UpdateIndex("title")
client.Index("books").UpdateIndex(&meilisearch.UpdateIndexRequestParams{
PrimaryKey: "title",
})
```

```csharp C#
Expand Down
8 changes: 8 additions & 0 deletions snippets/samples/code_samples_ranking_score_threshold.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<CodeGroup>

```dart Dart
await client
.index('INDEX_NAME')
.search('badman', SearchQuery(rankingScoreThreshold: 0.2));
```
</CodeGroup>
7 changes: 7 additions & 0 deletions snippets/samples/code_samples_rename_an_index_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ curl \
-H 'Content-Type: application/json' \
--data-binary '{ "uid": "INDEX_B" }'
```

```rust Rust
curl \
-X PATCH 'MEILISEARCH_URL/indexes/INDEX_A' \
-H 'Content-Type: application/json' \
--data-binary '{ "uid": "INDEX_B" }'
```
</CodeGroup>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<CodeGroup>

```bash cURL
curl \
-X DELETE 'MEILISEARCH_URL/indexes/INDEX_UID/settings/vector-store'
```
</CodeGroup>
9 changes: 9 additions & 0 deletions snippets/samples/code_samples_swap_indexes_2.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<CodeGroup>

```go Go
client.SwapIndexes([]SwapIndexesParams{
{Indexes: []string{"indexA", "indexB"}, Rename: true},
{Indexes: []string{"indexX", "indexY"}, Rename: true},
})
```
</CodeGroup>
6 changes: 6 additions & 0 deletions snippets/samples/code_samples_typo_tolerance_guide_5.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ $client->index('movies')->updateTypoTolerance([
]);
```

```java Java
TypoTolerance typoTolerance = new TypoTolerance();
typoTolerance.setDisableOnNumbers(true);
client.index("movies").updateTypoToleranceSettings(typoTolerance);
```

```ruby Ruby
index('books').update_typo_tolerance({ disable_on_numbers: true })
```
Expand Down
4 changes: 3 additions & 1 deletion snippets/samples/code_samples_update_an_index_1.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ client.index('movies').update(primary_key: 'movie_id')
```

```go Go
client.Index("movies").UpdateIndex("id")
client.Index("movies").UpdateIndex(&meilisearch.UpdateIndexRequestParams{
PrimaryKey: "id",
})
```

```csharp C#
Expand Down
8 changes: 8 additions & 0 deletions snippets/samples/code_samples_update_an_index_2.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<CodeGroup>

```go Go
client.Index("movies").UpdateIndex(&meilisearch.UpdateIndexRequestParams{
UID: "movies_index_rename",
})
```
</CodeGroup>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<CodeGroup>

```bash cURL
curl \
-X PUT 'MEILISEARCH_URL/indexes/INDEX_UID/settings/vector-store' \
-H 'Content-Type: application/json' \
--data-binary '"experimental"'
```
</CodeGroup>