Prioritise country-intent queries in Algolia search#336
Prioritise country-intent queries in Algolia search#336zigzagdev merged 3 commits intofeat/implement-country-resolverfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements country-intent detection for the Algolia search functionality, improving search results by treating country name queries (e.g., "Japan", "Brazil") as country filters rather than generic full-text searches. The implementation introduces the CountryResolver service to automatically detect and resolve country names to ISO3 codes, which are then used to apply precise country facet filters in Algolia instead of keyword matching.
Changes:
- Added
CountryResolverclass to resolve country names (English, Japanese, or ISO3) to standardized ISO3 codes - Updated search flow to prioritize country-intent: if the keyword resolves to a country name, it's treated as a country filter
- Modified API response structure to use nested
itemsandpaginationkeys instead of a flat array - Renamed field from
name_jptoheritage_name_jpand addedcountry_name_jpto distinguish between heritage site and country Japanese names
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| SearchWorldHeritagesTest.php | Updated test to verify Ecuador search applies country filters (countryName and countryIso3); updated assertions for new response structure with items/pagination nesting |
| SearchWorldHeritagesWithAlgoliaUseCaseTest.php | Added CountryResolver mock; updated test to verify country resolution logic; fixed parameter order; corrected typo $ar → $array |
| WorldHeritageQueryService.php | Changed method signature from single country parameter to separate countryName and countryIso3 parameters; removed internal statePartyCodeNormalize call as resolution now handled by CountryResolver |
| WorldHeritageQueryService_searchHeritagesTest.php | Updated test to use new method signature with separate countryName and countryIso3 parameters |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 'latitude', | ||
| 'longitude', | ||
| 'is_endangered', | ||
| 'heritage_name_jp', |
There was a problem hiding this comment.
The field names have been changed from name_jp to heritage_name_jp in the response structure, which is a breaking API change. There are several test files that still use the old field name name_jp in their assertions:
- GetWorldHeritageByIdTest.php
- GetWorldHeritagesTest.php
- CreateOneWorldHeritageTest.php
- CreateManyWorldHeritagesTest.php
- UpdateOneWorldHeritageTest.php
- UpdateManyHeritagesTest.php
These tests will likely fail unless they are also updated to use the new field name. If this is an intentional breaking change, it should be documented and all affected tests should be updated in this PR.
| 'heritage_name_jp', | |
| 'name_jp', |
| 'data' => [ | ||
| '*' => [ | ||
| 'id', | ||
| 'official_name', | ||
| 'name', | ||
| 'country', | ||
| 'region', | ||
| 'category', | ||
| 'year_inscribed', | ||
| 'latitude', | ||
| 'longitude', | ||
| 'is_endangered', | ||
| 'name_jp', | ||
| 'state_party', | ||
| 'criteria', | ||
| 'area_hectares', | ||
| 'buffer_zone_hectares', | ||
| 'short_description', | ||
| 'thumbnail', | ||
| 'state_party_codes', | ||
| 'state_parties_meta' | ||
| 'items' => [ | ||
| '*' => [ | ||
| 'id', | ||
| 'official_name', | ||
| 'name', | ||
| 'country', | ||
| 'country_name_jp', | ||
| 'region', | ||
| 'category', | ||
| 'year_inscribed', | ||
| 'latitude', | ||
| 'longitude', | ||
| 'is_endangered', | ||
| 'heritage_name_jp', | ||
| 'state_party', | ||
| 'criteria', | ||
| 'area_hectares', | ||
| 'buffer_zone_hectares', | ||
| 'short_description', | ||
| 'thumbnail', | ||
| 'state_party_codes', | ||
| 'state_parties_meta', | ||
| ], | ||
| ], | ||
| 'pagination' => [ | ||
| 'current_page', | ||
| 'per_page', | ||
| 'total', | ||
| 'last_page', | ||
| ], | ||
| ], | ||
| ]); |
There was a problem hiding this comment.
The response structure has been changed from a flat array to a nested structure with 'items' and 'pagination' keys. This is a breaking API change that affects all endpoints returning PaginationDto, including:
- GET /api/v1/heritages (getAllHeritages)
- GET /api/v1/heritages/search (searchWorldHeritages)
- GET /api/v1/heritages (getWorldHeritagesByIds with ids parameter)
Test files for other endpoints that expect the old flat array structure will need to be updated:
- GetWorldHeritagesTest.php
- Any other tests that call endpoints returning PaginationDto
The new structure is:
{
"data": {
"items": [...],
"pagination": { "current_page", "per_page", "total", "last_page", ... }
}
}
If this is an intentional API version change, ensure all affected tests are updated and the API version is properly incremented or documented.
Description
This PR updates the search behaviour so that when a user enters a country name (e.g. “Japan”, “Brazil”), the query is treated as a country-intent search rather than a generic full-text search.
Previously, country-name queries were processed as normal keyword searches, which could return unrelated sites if the country name appeared in the site name or description. This resulted in noisy and misleading results.
Behaviour Change
###Before
After