-
Notifications
You must be signed in to change notification settings - Fork 65
Add _insidePolygon support to geosearch #1414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds insidePolygon support: adaptGeoSearch now recognizes and validates polygon coordinates to emit a _geoPolygon filter (taking precedence over other geo params). Wires insidePolygon through the search-params adapter, updates tests and test types to include optional Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant UI as InstantSearch Widget
participant SPA as search-params-adapter
participant GRA as geo-rules-adapter
participant MS as Meilisearch
UI->>SPA: build search params (insidePolygon, insideBoundingBox, around*)
SPA->>GRA: adaptGeoSearch({ insidePolygon, ... })
alt insidePolygon valid (>=3 points)
note right of GRA #DFF2E1: Validate points, strip invalid\nFormat as ["lat, lng", ...]
GRA-->>SPA: return _geoPolygon filter
else no valid polygon
note right of GRA #FFF4E5: Fallback to aroundLatLng/aroundRadius\nor insideBoundingBox (existing logic)
GRA-->>SPA: return other geo filter or undefined
end
SPA->>MS: search(query, filters including _geoPolygon if present)
MS-->>SPA: hits
SPA-->>UI: results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts (1)
19-22
: Consider adding precision control for consistency.Unlike the existing
aroundLatLng
handling (line 35) which uses.toFixed(5)
to control floating-point precision, the polygon coordinates don't limit decimal places. While not critical, this inconsistency could lead to unexpected filter strings with high-precision input.Apply this diff for consistency:
- const lat = Number.parseFloat(String(pair[0])) - const lng = Number.parseFloat(String(pair[1])) + const lat = Number.parseFloat(String(pair[0])).toFixed(5) + const lng = Number.parseFloat(String(pair[1])).toFixed(5) if (Number.isNaN(lat) || Number.isNaN(lng)) return null - return `[${lat}, ${lng}]` + return `[${Number(lat)}, ${Number(lng)}]`Note: This mirrors the precision handling used for
aroundLatLng
at line 35.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/instant-meilisearch/__tests__/assets/utils.ts
(1 hunks)packages/instant-meilisearch/__tests__/geosearch.test.ts
(2 hunks)packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/geo-rules.test.ts
(1 hunks)packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts
(2 hunks)packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
packages/instant-meilisearch/__tests__/geosearch.test.ts (1)
packages/instant-meilisearch/__tests__/assets/utils.ts (1)
City
(225-230)
packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/geo-rules.test.ts (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts (1)
adaptGeoSearch
(3-65)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts (1)
adaptGeoSearch
(3-65)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: autocomplete-client end-to-end-tests
- GitHub Check: instant-meilisearch end-to-end-tests
🔇 Additional comments (8)
packages/instant-meilisearch/__tests__/assets/utils.ts (1)
107-222
: LGTM! GeoJSON support correctly added to test data.The implementation correctly adds
_geojson
fields alongside existing_geo
fields, properly following the GeoJSON Point format with coordinates in [longitude, latitude] order. The optional type annotation is appropriate since not all documents may have GeoJSON data.Also applies to: 229-229
packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts (1)
14-30
: Polygon precedence correctly implemented.The logic properly prioritizes
insidePolygon
over other geo filters and includes robust validation:
- Filters invalid coordinate pairs
- Ensures at least 3 valid points for a valid polygon
- Short-circuits to avoid unnecessary processing
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
207-222
: LGTM! Parameter correctly threaded through.The
insidePolygon
parameter is properly destructured from the search context and passed toadaptGeoSearch
, maintaining consistency with how other geo parameters are handled.packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/geo-rules.test.ts (1)
85-136
: Excellent test coverage for polygon functionality.The test suite comprehensively validates:
- Polygon conversion for different shapes (triangle, quadrilateral)
- Precedence behavior ensuring
insidePolygon
takes priority overinsideBoundingBox
and radius-based filters- Graceful handling of invalid input with fewer than 3 points
The expected filter format
_geoPolygon([lat, lng], ...)
correctly matches Meilisearch's syntax.packages/instant-meilisearch/__tests__/geosearch.test.ts (4)
14-14
: Filterable attributes correctly expanded for polygon support.Adding
'_geojson'
to the filterable attributes alongside'_geo'
enables polygon-based geo search. This aligns with Meilisearch v1.22.0's polygon support requirements.
112-133
: LGTM! Polygon search test validates expected behavior.The test correctly verifies that documents within the defined polygon (Brussels) are included while documents outside (Paris) are excluded, demonstrating that the
insidePolygon
parameter is properly translated into a working_geoPolygon
filter.
135-168
: Good coverage of _geojson field requirement.This test correctly validates an important constraint: the
_geoPolygon
filter in Meilisearch only matches documents with the_geojson
field. Documents with only_geo
are properly excluded from polygon searches. The test includes appropriate cleanup of the test document.
170-202
: Validates interoperability between _geo and _geojson fields.This test confirms that radius-based geo searches (using
_geoRadius
) work with documents that have only_geojson
fields, demonstrating good backward compatibility in Meilisearch's geo search implementation. The test includes proper cleanup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts (1)
14-30
: Consider: Coordinate precision consistency.For consistency with
aroundLatLng
processing (line 35, which uses.toFixed(5)
), consider whether polygon coordinates should also be formatted to 5 decimal places. However, this may not be necessary if Meilisearch handles precision internally.If desired for consistency:
const formattedPoints = insidePolygon .map((pair) => { if (!Array.isArray(pair) || pair.length < 2) return null const lat = Number.parseFloat(String(pair[0])) const lng = Number.parseFloat(String(pair[1])) if (Number.isNaN(lat) || Number.isNaN(lng)) return null - return `[${lat}, ${lng}]` + return `[${lat.toFixed(5)}, ${lng.toFixed(5)}]` }) .filter((pt): pt is string => pt !== null)packages/instant-meilisearch/__tests__/geosearch.test.ts (1)
135-171
: Document _geojson requirement for polygon geosearch
Polygon filters (insidePolygon
/_geoPolygon
) only work with GeoJSON shapes (_geojson
). Update the geosearch docs (README or API reference) to note that documents must include a valid_geojson
field to be returned in polygon searches (you can retain_geo
for distance-based sorting).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/instant-meilisearch/__tests__/assets/utils.ts
(1 hunks)packages/instant-meilisearch/__tests__/geosearch.test.ts
(2 hunks)packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/geo-rules.test.ts
(1 hunks)packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts
(2 hunks)packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts (1)
adaptGeoSearch
(3-65)
packages/instant-meilisearch/__tests__/geosearch.test.ts (1)
packages/instant-meilisearch/__tests__/assets/utils.ts (1)
City
(285-290)
packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/geo-rules.test.ts (1)
packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts (1)
adaptGeoSearch
(3-65)
🔇 Additional comments (8)
packages/instant-meilisearch/src/adapter/search-request-adapter/search-params-adapter.ts (1)
207-231
: LGTM! Clean parameter threading.The addition of
insidePolygon
to the destructuring and its pass-through toadaptGeoSearch
correctly wires the new polygon geo-search capability. The change is minimal and aligns with the updated function signature.packages/instant-meilisearch/src/adapter/search-request-adapter/__tests__/geo-rules.test.ts (1)
85-136
: LGTM! Comprehensive test coverage for polygon geo-search.The new test suite thoroughly validates
insidePolygon
behavior:
- Basic functionality with triangle and quadrilateral polygons
- Precedence over
insideBoundingBox
andaround*
parameters- Graceful handling of invalid input (< 3 points)
The tests align well with the implementation and cover both happy paths and edge cases.
packages/instant-meilisearch/__tests__/assets/utils.ts (2)
285-290
: LGTM! Correct GeoJSON Point structure.The addition of the optional
_geojson
field correctly models a GeoJSON Point with coordinates in[lng, lat]
order, which is the GeoJSON standard. The optional nature maintains backward compatibility with existing tests.
107-282
: Coordinate consistency confirmed. All entries ingeoDataset
have matching_geo
and_geojson
coordinates.packages/instant-meilisearch/__tests__/geosearch.test.ts (3)
14-14
: LGTM! Necessary filterable attribute addition.Adding
'_geojson'
to the filterable attributes is required for polygon-based geo queries to function properly in Meilisearch.
112-133
: LGTM! Well-structured polygon geo-search test.The test correctly validates
insidePolygon
functionality by:
- Using a triangle polygon around the Brussels area
- Confirming Brussels is included in results
- Confirming Paris (far outside) is excluded
The polygon coordinates follow the
[lat, lng]
convention used by InstantSearch.
173-205
: LGTM! Good test coverage for _geojson compatibility.This test confirms that radius-based geo queries work with
_geojson
-only documents, demonstrating interoperability between the two geo field formats. Proper cleanup is included.packages/instant-meilisearch/src/adapter/search-request-adapter/geo-rules-adapter.ts (1)
14-30
: LGTM! Robust polygon validation and precedence logic.The implementation correctly:
- Validates polygon structure (array with ≥3 coordinate pairs)
- Parses and validates each coordinate pair, filtering invalid entries
- Ensures at least 3 valid points remain after validation
- Returns immediately to establish precedence over other geo filters
- Formats output consistent with existing
_geoRadius
and_geoBoundingBox
filtersThe validation is thorough with appropriate NaN checks and defensive array length checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/instant-meilisearch/README.md (2)
794-794
: Enhance documentation with reference link and clarify settings configuration.The
insidePolygon
documentation is clear, but could be improved:
- Add a link to Meilisearch's documentation on
_geojson
for users who need to understand how to configure their index- Consider adding a brief note that the
filterableAttributes
setting must be configured via the Meilisearch API or dashboard (before using this parameter)Apply this diff to add the documentation link:
-- `insidePolygon`: Filters search results to only include documents whose coordinates fall within a specified polygon. This parameter accepts an array of coordinate pairs `[[lat, lng], [lat, lng], ...]` that define the polygon vertices (minimum 3 points required). When `insidePolygon` is specified, it takes precedence over `insideBoundingBox` and `around*` parameters. **Note**: This feature requires `_geojson` to be added to your Meilisearch index's `filterableAttributes` setting. +- `insidePolygon`: Filters search results to only include documents whose coordinates fall within a specified polygon. This parameter accepts an array of coordinate pairs `[[lat, lng], [lat, lng], ...]` that define the polygon vertices (minimum 3 points required). When `insidePolygon` is specified, it takes precedence over `insideBoundingBox` and `around*` parameters. **Note**: This feature requires `_geojson` to be added to your Meilisearch index's [`filterableAttributes` setting](https://www.meilisearch.com/docs/reference/api/settings#filterable-attributes) (configured via the Meilisearch API or dashboard before performing searches).
821-839
: Clear and well-structured example.The usage example effectively demonstrates the
insidePolygon
feature with:
- Clear comments about the prerequisite settings
- Proper coordinate array format
- Valid polygon (3 vertices forming a triangle)
One minor improvement: Consider clarifying that the
filterableAttributes
setting must be configured using the Meilisearch settings API or dashboard before using this parameter, as it cannot be set directly in the InstantSearch configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/instant-meilisearch/README.md (1)
794-794
: Improve readability by breaking up the long paragraph.The documentation for
insidePolygon
is comprehensive but presented as a single 300+ character line, which impacts readability. Consider breaking it into a bulleted list.Apply this diff to improve readability:
-- `insidePolygon`: Filters search results to only include documents whose coordinates fall within a specified polygon. This parameter accepts an array of coordinate pairs `[[lat, lng], [lat, lng], ...]` that define the polygon vertices (minimum 3 points required). When `insidePolygon` is specified, it takes precedence over `insideBoundingBox` and `around*` parameters. Polygon filters require documents to contain a valid `_geojson` field with [GeoJSON format](https://geojson.org/). Documents without `_geojson` will not be returned in polygon searches, even if they have `_geo` coordinates. +- `insidePolygon`: Filters search results to only include documents whose coordinates fall within a specified polygon. + - Accepts an array of coordinate pairs: `[[lat, lng], [lat, lng], ...]` (minimum 3 points required) + - Takes precedence over `insideBoundingBox` and `around*` parameters when specified + - Requires documents to contain a valid `_geojson` field with [GeoJSON format](https://geojson.org/) + - Documents without `_geojson` will not be returned in polygon searches, even if they have `_geo` coordinates
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/instant-meilisearch/README.md
(2 hunks)playgrounds/geo-javascript/index.html
(1 hunks)playgrounds/geo-javascript/src/app.js
(3 hunks)
✅ Files skipped from review due to trivial changes (1)
- playgrounds/geo-javascript/index.html
🧰 Additional context used
🧬 Code graph analysis (1)
playgrounds/geo-javascript/src/app.js (4)
playgrounds/javascript/src/app.js (1)
search
(4-13)packages/instant-meilisearch/src/client/instant-meilisearch-client.ts (1)
instantMeiliSearch
(46-212)playgrounds/node-env/index.js (1)
instantMeiliSearch
(4-8)playgrounds/react/src/App.jsx (1)
instantMeiliSearch
(18-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: instant-meilisearch end-to-end-tests
🔇 Additional comments (4)
playgrounds/geo-javascript/src/app.js (3)
5-5
: LGTM: Correct environment variable access for modern bundlers.The change from
process.env.GOOGLE_API
toimport.meta.env.GOOGLE_API
is appropriate for Vite or other modern bundlers that useimport.meta.env
for environment variables.
11-11
: LGTM: Index name updated consistently.The index name change from
world_cities
toworld_cities_geojson
aligns with the PR's addition of polygon support and is consistently applied across all references.Also applies to: 23-31
13-13
: Verify Meilisearch host and index accessibility. A direct check againsthttps://edge.meilisearch.com/indexes/world_cities_geojson
with the existing API key returned 401. Ensure thatedge.meilisearch.com
is the correct host, the API key has access, and theworld_cities_geojson
index exists there.packages/instant-meilisearch/README.md (1)
820-834
: LGTM: Clear and helpful polygon filtering example.The code example demonstrates
insidePolygon
usage effectively, following the existing documentation patterns. The coordinates form a valid triangle around Brussels (matching the test data), and the reference to the geosearch documentation provides users with additional context.
// instantsearch.widgets.geoSearch({ | ||
// container: '#maps', | ||
// googleReference: window.google, | ||
// initialZoom: 7, | ||
// initialPosition: { | ||
// lat: 50.655250871381355, | ||
// lng: 4.843585698860502, | ||
// }, | ||
// }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: geoSearch widget should not be commented out.
The geoSearch
widget is completely commented out in this geo-javascript playground. This is problematic because:
- This playground is specifically for demonstrating geosearch functionality
- The PR adds
insidePolygon
support, which should be demonstrated here - Users rely on this playground as a working example
The widget should be active to demonstrate the new polygon filtering feature.
Apply this diff to restore and enhance the geoSearch widget:
- // instantsearch.widgets.geoSearch({
- // container: '#maps',
- // googleReference: window.google,
- // initialZoom: 7,
- // initialPosition: {
- // lat: 50.655250871381355,
- // lng: 4.843585698860502,
- // },
- // }),
+ instantsearch.widgets.configure({
+ insidePolygon: [
+ [50.8466, 4.35],
+ [50.75, 4.1],
+ [50.65, 4.5],
+ ],
+ }),
+ instantsearch.widgets.geoSearch({
+ container: '#maps',
+ googleReference: window.google,
+ initialZoom: 7,
+ initialPosition: {
+ lat: 50.655250871381355,
+ lng: 4.843585698860502,
+ },
+ }),
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// instantsearch.widgets.geoSearch({ | |
// container: '#maps', | |
// googleReference: window.google, | |
// initialZoom: 7, | |
// initialPosition: { | |
// lat: 50.655250871381355, | |
// lng: 4.843585698860502, | |
// }, | |
// }), | |
instantsearch.widgets.configure({ | |
insidePolygon: [ | |
[50.8466, 4.35], | |
[50.75, 4.1], | |
[50.65, 4.5], | |
], | |
}), | |
instantsearch.widgets.geoSearch({ | |
container: '#maps', | |
googleReference: window.google, | |
initialZoom: 7, | |
initialPosition: { | |
lat: 50.655250871381355, | |
lng: 4.843585698860502, | |
}, | |
}), |
🤖 Prompt for AI Agents
playgrounds/geo-javascript/src/app.js around lines 40 to 48: the geoSearch
widget is fully commented out which breaks this geo demo and hides the new
insidePolygon feature; uncomment the geoSearch widget block so it is
instantiated, keep container: '#maps', googleReference: window.google,
initialZoom and initialPosition, and enhance the widget config to demonstrate
polygon filtering by adding an example insidePolygon parameter (provide a sample
polygon coordinate array or enable the insidePolygon option supported by the
widget) so the playground shows the new insidePolygon behavior.
@dureuill I know JS is not your main language, but it's more a review for the geosearch part, if relevant, to help Bruno who has less context on Geosearch. Tell me if not at all. |
The feature is ready but I need to do #1415 to update the geosearch playground |
Pull Request
Related issue
Fixes #1412
What does this PR do?
insidePolygon
from instantSearch params_geo
and_geojson
interactPR checklist
Please check if your PR fulfills the following requirements:
Thank you so much for contributing to Meilisearch!
Summary by CodeRabbit
New Features
Bug Fixes / Stability
Tests
Documentation