Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,4 @@ cypress/plugins
cypress/fixtures

.vscode
data.ms
18 changes: 18 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,24 @@ Or the HTML playground:
yarn playground:html
```

### Geo-Search Playground

A playground is available to try out the [GeoSearch](./README.md/-geo-search) in `instant-meilisearch`.

Unfortunately, for the moment, no online dataset is provided. Meaning that to make the playground work, you will have to set up your MeiliSearch accordingly to the playground needs.

To do so follow these steps:

1. Run a MeiliSeaerch instance. See [Setup](#setup) section to launch MeiliSearch with `Docker`. It is important to use the same `host` and `apikey` as provided in the `setup` section.
2. Add the settings and the documents to your running MeiliSearch instance. We provide a script that does this automatically. Please run `node playgrounds/geo-javascript/setup/index.js`. Or you can look at the script to take inspiration!
4. Run the playground!

```bash
yarn playground:geo-javascript
```

Note: If the Google Maps stopped working, please create a new [Google Api Key](https://developers.google.com/maps/documentation/javascript/get-api-key) and add it in the `.env` file at the root of the playground: `/playgrounds/geo-javascript`

## Git Guidelines

### Git Branches <!-- omit in TOC -->
Expand Down
91 changes: 88 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,13 +474,98 @@ instantsearch.widgets.hits({
})
```

### Geo Search
### Geo Search

[Geo search references](https://www.algolia.com/doc/api-reference/widgets/geo-search/js/)

No compatibility because MeiliSearch does not support Geo Search.
The `geoSearch` widget displays search results on a Google Map. It lets you search for results based on their position and provides some common usage patterns such as “search on map interactions”.

If you'd like to see it implemented please vote for it in the [roadmap](https://roadmap.meilisearch.com/c/33-geo-search?utm_medium=social&utm_source=portal_share).
- ✅ container: The CSS Selector or HTMLElement to insert the Google maps into. _required_
- ✅ googleReference: The reference to the global window.google object. See the [Google Maps](https://developers.google.com/maps/documentation/javascript/overview) documentation for more information. _required_

- ✅ initialZoom: When no search results are found, google map will default to this zoom.
- ✅ initialPosition: When no search results are found, google map will default to this position.
- ✅ mapOptions: The options forwarded to the Google Maps constructor.
- ❔ builtInMarker: Used to customize Google Maps markers. Because of lack of tests we cannot guarantee its compatibility. For more information please visit [InstantSearch related documentation](https://www.algolia.com/doc/api-reference/widgets/geo-search/js/#widget-param-builtinmarker).
- customHTMLMarker: Same as `builtInMarker`. Because of lack of tests, we cannot guarantee its compatibility. For more information please visit [InstantSearch related documentation](https://www.algolia.com/doc/api-reference/widgets/geo-search/js/#widget-param-customhtmlmarker).
- ✅ enableRefine: If true, the map is used for refining the search. Otherwise, it’s only for display purposes.
- ✅ enableClearMapRefinement: If `true`, a button is displayed on the map when the refinement is coming from interacting with it, to remove it.
- ✅ enableRefineControl: If `true`, the map is used for refining the search. Otherwise, it’s only for display purposes.
- ✅ enableRefineOnMapMove: If `true`, a button is displayed on the map when the refinement is coming from interacting with it, to remove it.,
- ✅ templates: The templates to use for the widget.
- ✅ cssClasses: The CSS classes to override.

[See our playground for a working exemple](./playgrounds/geo-javascript/src/app.js) and this section in our [contributing guide](./CONTRIBUTING.md#-geo-search-playground) to set up your `MeiliSearch`.

#### Requirements

The Geosearch widgey only works with a valid Google API key.

In order to communicate your Google API key, your `instantSearch` widget should be surrounded by the following function:

```js
import injectScript from 'scriptjs'

injectScript(
`https://maps.googleapis.com/maps/api/js?v=quarterly&key=${GOOGLE_API}`,
() => {
const search = instantsearch({
indexName: 'geo',
// ...
})
// ...
})
```

Replace `${GOOGLE_API}` with you google api key.

See [code example in the playground](./playgrounds/geo-javascript/src/app.js)

### Usage

The classic usage, with only the `required` elements, renders an embedded Google Map on which you can move and refine search based on the position maps.

```js
instantsearch.widgets.geoSearch({
container: '#maps',
googleReference: window.google,
}),
```

For further customization, for example to determine an initial position for the map. Contrary to `initialZoom` and `initialPosition`, triggers a search request with the provided information.

The following parameters exist:

- `boundingBox`: The Google Map window box. It is used as parameter in a search request. It takes precedent on all the following parameters.
- `aroundLatLng`: The middle point of the Google Map. If `insideBoundingBox` or `boundingBox` is present, it is ignored.
- `aroundRadius`: The radius around a Geo Point, used for sorting in the search request. It only works if `aroundLatLng` is present as well. If `insideBoundingBox` or `boundingBox` is present, it is ignored.


For exemple, by adding `boundingBox` in the [`instantSearch`](#-instantsearch) widget parameters, the parameter will be used as a search parameter for the first request.

```js
initialUiState: {
geo: {
geoSearch: {
boundingBox:
'50.680720183653065, 3.273798366642514,50.55969330590075, 2.9625244444490253',
},
},
},
```
Without providing this parameter, Google Maps will default to a window containing all markers from the provided search results.

Alternatively, the parameters can be passed through the [`searchFunction`](https://www.algolia.com/doc/api-reference/widgets/instantsearch/js/#widget-param-searchfunction) parameter of the [`instantSearch`](#-instantsearch) widget. Contrary to `initialUiState` these parameters overwrite the values on each search.

```js
searchFunction: function (helper) {
helper.setQueryParameter('aroundRadius', 75000)
helper.setQueryParameter('aroundLatLng', '51.1241999, 9.662499900000057');
helper.search()
},
```

[Read the guide on how GeoSearch works in MeiliSearch](https://docs.meilisearch.com/reference/features/geosearch.html#geosearch).

### ❌ Answers

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"playground:vue": "yarn --cwd ./playgrounds/vue && yarn --cwd ./playgrounds/vue serve",
"playground:react": "yarn --cwd ./playgrounds/react && yarn --cwd ./playgrounds/react start",
"playground:javascript": "yarn --cwd ./playgrounds/javascript && yarn --cwd ./playgrounds/javascript start",
"playground:geo-javascript": "yarn --cwd ./playgrounds/geo-javascript && yarn --cwd ./playgrounds/geo-javascript start",
"playground:html": "yarn --cwd ./playgrounds/html && yarn --cwd ./playgrounds/html start",
"playground:angular": "yarn --cwd ./playgrounds/angular && yarn --cwd ./playgrounds/angular start",
"postbuild": "yarn typingsheader",
Expand Down
1 change: 1 addition & 0 deletions playgrounds/geo-javascript/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GOOGLE_API=AIzaSyDOaUaar4GL0i99LpN2zQHzfWXL1wu_JQo
21 changes: 21 additions & 0 deletions playgrounds/geo-javascript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Javascript GeoSearch Playground

To run this playground you will first have to set up your MeiliSearch accordingly to the playground needs. To do so please follow the steps in our [contributing guide](./CONTRIBUTING.md#-geo-search-playground).

The provided Google Maps Api Key is limited at 300 requests per day, so it might be down sometimes. In which case, please create a new [Google Api Key](https://developers.google.com/maps/documentation/javascript/get-api-key) and add it in the `.env` file at the root of the playground: `/playgrounds/geo-javascript`

## Project setup

```
yarn install
```

### Compiles and hot-reloads for development
```
yarn start
```

### Compiles and minifies for production
```
yarn build
```
38 changes: 38 additions & 0 deletions playgrounds/geo-javascript/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="theme-color" content="#000000" />

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css" />
<link rel="stylesheet" href="./src/index.css" />
<link rel="stylesheet" href="./src/app.css" />

<title>MeiliSearch + InstantSearch 🌍</title>
</head>

<body>
<div class="ais-InstantSearch">
<h1>MeiliSearch + InstantSearch.js</h1>
<h2>Search in European cities </h2>
<p>
This is a small dataset of ~20K european countries which might be missing big cities as they were fetched
randomly.
</p>

<div class="right-panel">
<div id="searchbox" class="ais-SearchBox"></div>
<div id="maps" style="height: 500px; width: 500px"></div>
<br>
<div id="hits"></div>
<div id="pagination"></div>
</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4"></script>
<script src="/src/app.js"></script>
</body>

</html>
28 changes: 28 additions & 0 deletions playgrounds/geo-javascript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "js-playground",
"version": "0.1.0",
"description": "Instant-meilisearch playground focussed on GeoSearch written with vanilla javascript",
"main": "index.js",
"scripts": {
"start": "parcel serve index.html --open",
"build": "parcel build index.html"
},
"devDependencies": {
"@babel/core": "^7.13.1",
"parcel-bundler": "^1.12.4"
},
"resolutions": {
"node-forge": "^0.10.0"
},
"browserslist": [
"last 3 and_chr versions",
"last 3 chrome versions",
"last 3 opera versions",
"last 3 ios_saf versions",
"last 3 safari versions"
],
"license": "MIT",
"dependencies": {
"scriptjs": "^2.5.9"
}
}
162 changes: 162 additions & 0 deletions playgrounds/geo-javascript/setup/countries.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
[
{
"id": "1",
"city": "Lille",
"_geo": {
"lat": 50.629973371633746,
"lng": 3.056944739941957
}
},
{
"id": "2",
"city": "Mons-en-Barœul",
"_geo": {
"lat": 50.64158612012105,
"lng": 3.110659348034867
}
},
{
"id": "3",
"city": "Hellemmes",
"_geo": {
"lat": 50.63122096551808,
"lng": 3.1106399673339933
}
},
{
"id": "4",
"city": "Villeneuve-d'Ascq",
"_geo": {
"lat": 50.622468098014565,
"lng": 3.147642551343714
}
},
{
"id": "5",
"city": "Hem",
"_geo": {
"lat": 50.655250871381355,
"lng": 3.189729726624413
}
},
{
"id": "6",
"city": "Roubaix",
"_geo": {
"lat": 50.69247345189671,
"lng": 3.176332673774765
}
},
{
"id": "7",
"city": "Tourcoing",
"_geo": {
"lat": 50.72639746673648,
"lng": 3.154165365957867
}
},
{
"id": "8",
"city": "Mouscron",
"_geo": {
"lat": 50.74532555490861,
"lng": 3.2206407854429853
}
},
{
"id": "9",
"city": "Tournai",
"_geo": {
"lat": 50.60534252860263,
"lng": 3.3758586941351414
}
},
{
"id": "10",
"city": "Ghent",
"_geo": {
"lat": 51.053777403679035,
"lng": 3.695773311992693
}
},
{
"id": "11",
"city": "Brussels",
"_geo": {
"lat": 50.84664097454469,
"lng": 4.337066356428184
}
},
{
"id": "12",
"city": "Charleroi",
"_geo": {
"lat": 50.40957013888948,
"lng": 4.434735431508552
}
},
{
"id": "13",
"city": "Mons",
"_geo": {
"lat": 50.45029417885542,
"lng": 3.962372287090469
}
},
{
"id": "14",
"city": "Valenciennes",
"_geo": {
"lat": 50.351817774473545,
"lng": 3.53262836469288
}
},
{
"id": "15",
"city": "Arras",
"_geo": {
"lat": 50.28448752857995,
"lng": 2.763751584447816
}
},
{
"id": "16",
"city": "Cambrai",
"_geo": {
"lat": 50.1793405779067,
"lng": 3.218940995250293
}
},
{
"id": "17",
"city": "Bapaume",
"_geo": {
"lat": 50.1112761272364,
"lng": 2.854789466608312
}
},
{
"id": "18",
"city": "Amiens",
"_geo": {
"lat": 49.931472529669996,
"lng": 2.271049975831708
}
},
{
"id": "19",
"city": "Compiègne",
"_geo": {
"lat": 49.444980887725656,
"lng": 2.7913841281529015
}
},
{
"id": "20",
"city": "Paris",
"_geo": {
"lat": 48.90210006089548,
"lng": 2.370840086740693
}
}
]
Loading