The /search endpoint provides powerful search capabilities across multiple content types (resorts, articles, regions, resort types, weather reports) with extensive filtering, faceting, sorting, and field selection options.
GET /search
q (string, optional)Search query term that searches across searchable fields for each content type.
Searchable fields by type:
name (with relevance boosting), descriptiontitle, descriptiontitle, subtitle, descriptiontitleRelevance scoring for resorts:
Examples:
q=Trysil - Find resorts/content matching "Trysil"q=ski - Find all content containing "ski"index (string, optional)Specifies which index to search. Defaults to resort index.
Allowed values:
resort (default) - Search resortsblog - Search blog posts/articlesExamples:
index=blog - Search blog articlesindex=resort - Search resorts (default)type (string, optional)Specifies the content type to search. Takes precedence over index parameter.
Allowed values:
resort (default) - Ski resortsblog_post - Blog articlesregion - Geographic regionsresort_type - Resort type categoriesweather_report - Weather reportsExamples:
type=resort - Search only resortstype=blog_post - Search only articlestype=region - Search only regionspage (integer, optional, default: 1)Page number for pagination (1-indexed).
Examples:
page=1 - First page (default)page=2 - Second pagesize (integer, optional, default: 20)Number of results per page.
Examples:
size=10 - Return 10 resultssize=50 - Return 50 resultsfacet (string, optional)Filter results by specific field values. Multiple facets can be combined using semicolon (;) separator. Multiple values within a single facet can be combined using comma (,) for OR logic.
Format: fieldName:value or fieldName:value1,value2 (OR logic) or field1:value1;field2:value2 (multiple facets)
Common facet fields:
resort_open:1 - Only open resortsresort_open:0 - Only closed resortsresort_type:Alpint - Resorts of type "Alpint"region:Trysil - Resorts in Trysil regionconditions.combined.top.snow.depth_terrain:50 - Snow depth equals 50cm at topExamples:
facet=resort_open:1 - Filter only open resortsfacet=resort_open:1;region:Oslo - Multiple facets (open resorts in Oslo region)facet=resort_type:Alpint,Langrenn - Multiple values for OR logic (Alpint OR Langrenn resorts)facet=resort_open:1;resort_type:Alpint,Familie - Combined: open resorts that are Alpint OR Familie typefacet=conditions.combined.top.snow.depth_terrain:100 - Filter by exact snow depthdateRange (string, optional)Filter by date range using ISO 8601 date format.
Format: YYYY-MM-DD or YYYY-MM-DDTHH:mm:ssZ (pipe-separated for range)
Applies to: created_at column
Examples:
dateRange=2024-01-01 - From Jan 1, 2024 onwardsdateRange=2024-01-01|2024-12-31 - Entire year 2024dateRange=2024-06-15T10:00:00Z|2024-06-20T18:00:00Z - Specific datetime rangerange (string, optional)Filter by numeric or date field ranges, supports ElasticSearch-style date expressions. Multiple range filters can be combined using a semicolon (;). All filters are ANDed together.
Format:
fieldName:value or fieldName:min|maxfieldName1:value1;fieldName2:min2|max2;...Date expressions (relative to current time):
now - Current date/timenow+1h - One hour from nownow-1d - One day agonow+2w - Two weeks from nownow-6M - Six months agonow+1Y - One year from nowSupported units:
y or Y - YearsM - Monthsw - Weeksd - Daysh or H - Hoursm - Minutess - SecondsExamples:
range=resort_opening_date:now — Resorts opening now or laterrange=resort_opening_date:now|now+1w — Resorts opening within next weekrange=lifts.open:5|20 — Resorts with 5-20 open liftsrange=conditions.combined.top.snow.depth_terrain:50|150 — Snow depth between 50-150cmrange=is_open:1 — Resorts currently open (uses business logic)range=lifts.open:1;is_open:1 — Resorts with open lifts that are currently openrange=lifts.open:5|20;slopes.open:10|30 — Resorts with 5-20 open lifts AND 10-30 open slopesrange=conditions.combined.top.snow.depth_terrain:100|200;is_open:1 — Open resorts with 100-200cm snow at the toprange=resort_opening_date:now|now+3M — Resorts opening within the next 3 monthsNote: Spaces in date expressions may be URL-encoded as + signs. Multiple range filters are combined using AND logic.
exists (string, optional)Filter results where a specific field exists and is not null/empty.
Behavior:
Examples:
exists=description - Only results with a descriptionexists=conditions.combined.top.powder_alarm - Only resorts with powder alarm data at topexists=images - Only results with imagesexists=lifts.open - Only resorts with open lifts datainclude (string, optional)Include only specific IDs in results (comma-separated).
Uses primary ID field:
site_idwp_idExamples:
include=14 - Include only resort with site_id=14include=14,12,89 - Include only resorts with IDs 14, 12, and 89exclude (string, optional)Exclude specific IDs from results (comma-separated).
Uses same ID fields as include
Examples:
exclude=14 - Exclude resort with site_id=14exclude=14,12 - Exclude resorts with IDs 14 and 12powderAlarm (boolean, optional)Filter resorts or weather reports with fresh powder snow conditions.
Applies to: resort and weather_report types only
Behavior:
conditions.combined.top.powder_alarm OR conditions.combined.bottom.powder_alarm is truepowder_alarm field is trueExamples:
powderAlarm=1 - Find resorts with fresh powderpowderAlarm=true - Same as abovetype=resort&powderAlarm=1&facet=resort_open:1 - Open resorts with fresh powdersort (string, optional, default: "created_at:desc")Sort results by field name and direction.
Format: fieldName:direction
Direction:
asc - Ascending orderdesc - Descending order (default)Examples:
sort=name:asc - Sort by name alphabeticallysort=resort_opening_date:asc - Sort by opening date (earliest first)sort=conditions.combined.top.snow.depth_terrain:desc - Sort by snow depth (highest first)sort=lifts.open:desc - Sort by number of open lifts (most first)sourceFields (string, optional)Return only specific fields from the _source object using dot notation (comma-separated).
Purpose: Optimize response payload size by requesting only needed fields
Supports nested field selection using dot notation.
Examples:
sourceFields=name,id - Return only name and idsourceFields=name,location.lat,location.lon - Return name and coordinatessourceFields=name,lifts.open,slopes.open - Return name and open lifts/slopes countssourceFields=conditions.combined.top.snow.depth_terrain - Return only top snow depth{
"took": 1,
"timed_out": false,
"hits": {
"total": 123,
"hits": [
{
"_index": "fnugg_resort",
"_type": "resort",
"_id": "14",
"_version": 1,
"found": true,
"_source": {
"id": 14,
"name": "Trysil",
"description": "Norges største alpinområde...",
"location": {
"lat": 61.315,
"lon": 12.268
},
"resort_open": true,
"conditions": {
"combined": {
"top": {
"snow": {
"depth": 120
},
"powder_alarm": true
}
}
}
// ... more fields
}
}
// ... more results
]
},
"aggregations": {
"snowfall_last_week": {
"doc_count": 10,
"zone": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "top",
"doc_count": 10,
"sum": {
"value": 45.0
}
}
]
}
},
"snowfall_last_five_months": {
"doc_count": 150,
"zone": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "top",
"doc_count": 75,
"sum": {
"value": 2340.5
}
},
{
"key": "bottom",
"doc_count": 75,
"sum": {
"value": 1820.0
}
}
]
}
},
"site": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
},
"resort_type": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
},
"zone": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
},
"type": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
},
"region": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
},
"total": 123
}
took (integer): Request processing time in milliseconds (always 1 for compatibility)timed_out (boolean): Whether request timed out (always false)hits.total (integer): Total number of matching resultshits.hits (array): Array of result objectsaggregations (object, optional): Aggregated statistics for the search results (see Aggregations section below)total (integer): Duplicate of hits.total for legacy compatibilityEach result in hits.hits contains:
_index (string): Index name (e.g., "fnugg_resort", "fnugg_blog")_type (string): Content type (e.g., "resort", "blog_post", "region")_id (string): Document ID_version (integer): Document version (always 1)found (boolean): Whether document was found (always true in search results)_source (object): The actual document data (structure varies by type)The aggregations object provides statistical summaries and grouped data for search results. The structure and content depends on the search type and parameters.
When searching type=weather_report parameter, the response includes snowfall statistics grouped by weather zone (top/bottom):
snowfall_last_weekTotal snowfall in the past 7 days, grouped by zone.
Structure:
doc_count (integer): Total number of weather reports in this time rangezone.buckets (array): Array of zone-specific statistics
key (string): Zone name ("top" or "bottom")doc_count (integer): Number of reports for this zonesum.value (float): Total snowfall in centimeters for this zoneExample:
{
"snowfall_last_week": {
"doc_count": 10,
"zone": {
"buckets": [
{
"key": "top",
"doc_count": 10,
"sum": { "value": 45.0 }
}
]
}
}
}
snowfall_last_five_monthsTotal snowfall in the past 5 months, grouped by zone. Uses the same structure as snowfall_last_week.
The following aggregation fields are maintained for backward compatibility with the previous ElasticSearch-based API but contain empty buckets:
site: Site/resort grouping (deprecated)zone: Weather zone grouping (deprecated)resort_type: Resort type categorization (deprecated)type: Content type grouping (deprecated)region: Geographic region grouping (deprecated)These fields always return empty bucket arrays:
{
"site": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": []
}
}
Note: those are present only to maintain API response structure compatibility.
GET /search?q=Trysil
Searches for resorts matching "Trysil" with relevance scoring.
GET /search?type=resort&facet=resort_open:1&powderAlarm=1&sort=conditions.combined.top.snow.depth_terrain:desc
Finds all open resorts with fresh powder, sorted by snow depth.
GET /search?type=resort&range=resort_opening_date:now|now+1w&sort=resort_opening_date:asc
Finds resorts opening within the next 7 days, sorted by opening date.
GET /search?index=blog&type=blog_post&dateRange=2024-01-01|2024-12-31&size=50
Searches all blog posts created in 2024, returning 50 results per page.
GET /search?type=weather_report&facet=site:24&size=10
Fetches weather reports for resort site_id 24, includes snowfall aggregations by zone for the past week and 5 months.
GET /search?type=resort&facet=region:Oslo&sourceFields=name,location.lat,location.lon,resort_open
Finds resorts in Oslo region, returning only name, coordinates, and open status.
GET /search?type=resort&range=conditions.combined.top.snow.depth_terrain:100|200&facet=resort_open:1
Finds open resorts with snow depth between 100-200cm at the top.
GET /search?q=familie&type=resort&facet=resort_open:1;resort_type:Alpint&range=lifts.open:5&exists=slope_map&sourceFields=name,lifts,slopes,location&size=10&page=1
Searches for family-friendly open alpine resorts with at least 5 open lifts and a slope map, returning name, lifts, slopes, and location for 10 results.
GET /search?type=resort&facet=resort_type:Alpint,Langrenn,Familie&facet=resort_open:1
Finds open resorts that are Alpint OR Langrenn OR Familie type.
type=resort&facet=resort_open:1type=resort&powderAlarm=1&facet=resort_open:1/geodata/getnearest to get nearby resort IDs, then search with include parameterinclude parameter with multiple IDs and sourceFields to get specific dataindex=blog&type=blog_post&q=<term>range=resort_opening_date:now|now+3M to find resorts opening in next 3 monthsrange=conditions.combined.top.snow.depth_terrain and enable powderAlarmtype=weather_report&facet=site:X to get snowfall aggregations by zoneq parameter unless explicit sort is provided;) separator (e.g., facet=resort_open:1;region:Oslo),) separator for OR logic (e.g., facet=resort_type:Alpint,Langrenn);) separator (e.g., range=is_open:1;resort_opening_date:now|now+1w). All range filters are combined using AND logic.conditions.combined.top.snow.depth_terrain)powderAlarm parameter only works for resort and weather_report typesfacet=field:1 or range=field:trueweather_report searches with a facet=site:X parameter. Legacy aggregation fields (site, zone, resort_type, type, region) return empty buckets for backward compatibility.