From 1bb21ff19cd04b3710f5b5f1c4ee84f453c5737c Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Tue, 16 Jun 2026 16:28:43 +0100 Subject: [PATCH 01/19] Add Algolia plugin --- plugins/Algolia/v1/configValidation.json | 11 + plugins/Algolia/v1/custom_types.json | 9 + plugins/Algolia/v1/dataStreams/indexes.json | 46 ++++ .../Algolia/v1/dataStreams/noResultRate.json | 44 ++++ .../v1/dataStreams/noResultSearches.json | 40 +++ .../Algolia/v1/dataStreams/searchCount.json | 37 +++ .../Algolia/v1/dataStreams/topSearches.json | 40 +++ .../v1/defaultContent/algoliaIndex.dash.json | 228 ++++++++++++++++++ .../Algolia/v1/defaultContent/manifest.json | 6 + .../v1/defaultContent/overview.dash.json | 209 ++++++++++++++++ plugins/Algolia/v1/defaultContent/scopes.json | 14 ++ plugins/Algolia/v1/docs/README.md | 52 ++++ plugins/Algolia/v1/icon.svg | 6 + .../Algolia/v1/indexDefinitions/default.json | 24 ++ plugins/Algolia/v1/metadata.json | 39 +++ plugins/Algolia/v1/ui.json | 28 +++ 16 files changed, 833 insertions(+) create mode 100644 plugins/Algolia/v1/configValidation.json create mode 100644 plugins/Algolia/v1/custom_types.json create mode 100644 plugins/Algolia/v1/dataStreams/indexes.json create mode 100644 plugins/Algolia/v1/dataStreams/noResultRate.json create mode 100644 plugins/Algolia/v1/dataStreams/noResultSearches.json create mode 100644 plugins/Algolia/v1/dataStreams/searchCount.json create mode 100644 plugins/Algolia/v1/dataStreams/topSearches.json create mode 100644 plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json create mode 100644 plugins/Algolia/v1/defaultContent/manifest.json create mode 100644 plugins/Algolia/v1/defaultContent/overview.dash.json create mode 100644 plugins/Algolia/v1/defaultContent/scopes.json create mode 100644 plugins/Algolia/v1/docs/README.md create mode 100644 plugins/Algolia/v1/icon.svg create mode 100644 plugins/Algolia/v1/indexDefinitions/default.json create mode 100644 plugins/Algolia/v1/metadata.json create mode 100644 plugins/Algolia/v1/ui.json diff --git a/plugins/Algolia/v1/configValidation.json b/plugins/Algolia/v1/configValidation.json new file mode 100644 index 00000000..4bd9fd7e --- /dev/null +++ b/plugins/Algolia/v1/configValidation.json @@ -0,0 +1,11 @@ +{ + "steps": [ + { + "displayName": "Authenticate", + "dataStream": { "name": "indexes" }, + "required": true, + "error": "Could not connect to Algolia. Check your Application ID is correct and that your API key has the 'listIndexes' ACL (a Search-Only key will not work).", + "success": "Connected to Algolia." + } + ] +} diff --git a/plugins/Algolia/v1/custom_types.json b/plugins/Algolia/v1/custom_types.json new file mode 100644 index 00000000..2ad28542 --- /dev/null +++ b/plugins/Algolia/v1/custom_types.json @@ -0,0 +1,9 @@ +[ + { + "name": "Algolia Index", + "sourceType": "Algolia Index", + "icon": "magnifying-glass", + "singular": "Index", + "plural": "Indices" + } +] diff --git a/plugins/Algolia/v1/dataStreams/indexes.json b/plugins/Algolia/v1/dataStreams/indexes.json new file mode 100644 index 00000000..fa708784 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/indexes.json @@ -0,0 +1,46 @@ +{ + "name": "indexes", + "displayName": "Indices", + "description": "Algolia indices in the application, with record counts, sizes, last build time and pending tasks.", + "tags": [], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "1/indexes", + "pathToData": "items", + "paging": { "mode": "none" } + }, + "matches": "none", + "metadata": [ + { "name": "name", "displayName": "Index", "role": "label" }, + { + "name": "entries", + "displayName": "Records", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "dataSize", + "displayName": "Data Size", + "shape": ["bytes", { "thousandsSeparator": true }] + }, + { + "name": "fileSize", + "displayName": "File Size", + "shape": ["bytes", { "thousandsSeparator": true }] + }, + { + "name": "lastBuildTimeS", + "displayName": "Last Build Time", + "shape": ["seconds", { "thousandsSeparator": true }] + }, + { + "name": "numberOfPendingTasks", + "displayName": "Pending Tasks", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { "name": "pendingTask", "displayName": "Has Pending Task" }, + { "name": "updatedAt", "displayName": "Last Updated" }, + { "name": "primary", "displayName": "Primary Index" } + ], + "timeframes": false +} diff --git a/plugins/Algolia/v1/dataStreams/noResultRate.json b/plugins/Algolia/v1/dataStreams/noResultRate.json new file mode 100644 index 00000000..a4175387 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/noResultRate.json @@ -0,0 +1,44 @@ +{ + "name": "noResultRate", + "displayName": "No-Result Rate", + "description": "Daily proportion of searches returning no results for an index", + "tags": [], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "baseUrl": "https://analytics.{{dataSource.analyticsRegion || 'us'}}.algolia.com", + "endpointPath": "/2/searches/noResultRate", + "getArgs": [ + { "key": "index", "value": "{{object.rawId}}" }, + { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, + { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" } + ], + "pathToData": "dates" + }, + "matches": { "sourceType": { "type": "equals", "value": "Algolia Index" } }, + "metadata": [ + { + "name": "date", + "displayName": "Date", + "shape": "date", + "role": "timestamp" + }, + { + "name": "rate", + "displayName": "No-result rate", + "shape": ["percent", { "asZeroToOne": true }], + "role": "value" + }, + { + "name": "count", + "displayName": "Searches", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "noResultCount", + "displayName": "No-result searches", + "shape": ["number", { "decimalPlaces": 0 }] + } + ], + "timeframes": true +} diff --git a/plugins/Algolia/v1/dataStreams/noResultSearches.json b/plugins/Algolia/v1/dataStreams/noResultSearches.json new file mode 100644 index 00000000..e65a98a2 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/noResultSearches.json @@ -0,0 +1,40 @@ +{ + "name": "noResultSearches", + "displayName": "Top Searches With No Results", + "description": "Most frequent searches that returned no results for an index", + "tags": [], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "baseUrl": "https://analytics.{{dataSource.analyticsRegion || 'us'}}.algolia.com", + "endpointPath": "/2/searches/noResults", + "getArgs": [ + { "key": "index", "value": "{{object.rawId}}" }, + { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, + { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" }, + { "key": "limit", "value": "50" } + ], + "pathToData": "searches", + "paging": { "mode": "none" } + }, + "matches": { "sourceType": { "type": "equals", "value": "Algolia Index" } }, + "metadata": [ + { + "name": "search", + "displayName": "Search", + "shape": "string", + "role": "label" + }, + { + "name": "count", + "displayName": "Count", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "withFilterCount", + "displayName": "With filters", + "shape": ["number", { "decimalPlaces": 0 }] + } + ], + "timeframes": true +} diff --git a/plugins/Algolia/v1/dataStreams/searchCount.json b/plugins/Algolia/v1/dataStreams/searchCount.json new file mode 100644 index 00000000..7d4dca26 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/searchCount.json @@ -0,0 +1,37 @@ +{ + "name": "searchCount", + "displayName": "Search Count", + "description": "Daily number of searches for an index over the selected timeframe", + "tags": [], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "baseUrl": "https://analytics.{{dataSource.analyticsRegion || 'us'}}.algolia.com", + "endpointPath": "/2/searches/count", + "getArgs": [ + { "key": "index", "value": "{{object.rawId}}" }, + { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, + { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" } + ], + "pathToData": "dates" + }, + "matches": { "sourceType": { "type": "equals", "value": "Algolia Index" } }, + "metadata": [ + { + "name": "date", + "displayName": "Date", + "shape": "date", + "role": "timestamp" + }, + { + "name": "count", + "displayName": "Searches", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "value" + }, + { + "pattern": ".*" + } + ], + "timeframes": true +} diff --git a/plugins/Algolia/v1/dataStreams/topSearches.json b/plugins/Algolia/v1/dataStreams/topSearches.json new file mode 100644 index 00000000..1c8c1878 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/topSearches.json @@ -0,0 +1,40 @@ +{ + "name": "topSearches", + "displayName": "Top Searches", + "description": "Most frequent search queries for an index over the selected timeframe", + "tags": [], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "baseUrl": "https://analytics.{{dataSource.analyticsRegion || 'us'}}.algolia.com", + "endpointPath": "/2/searches", + "getArgs": [ + { "key": "index", "value": "{{object.rawId}}" }, + { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, + { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" }, + { "key": "limit", "value": "50" } + ], + "pathToData": "searches", + "paging": { "mode": "none" } + }, + "matches": { "sourceType": { "type": "equals", "value": "Algolia Index" } }, + "metadata": [ + { + "name": "search", + "displayName": "Search", + "shape": "string", + "role": "label" + }, + { + "name": "count", + "displayName": "Count", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "nbHits", + "displayName": "Results", + "shape": ["number", { "decimalPlaces": 0 }] + } + ], + "timeframes": true +} diff --git a/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json b/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json new file mode 100644 index 00000000..708e2851 --- /dev/null +++ b/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json @@ -0,0 +1,228 @@ +{ + "name": "Algolia Index", + "schemaVersion": "1.5", + "timeframe": "last30days", + "variables": ["{{variables.[Algolia Index]}}"], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "9b9fc2b9-c56d-47de-a4c4-d151e467a210", + "x": 0, + "y": 6, + "w": 4, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Index Details", + "description": "", + "timeframe": "none", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "datastream-properties", + "pluginConfigId": "{{configId}}" + }, + "scope": { + "scope": "{{scopes.[Algolia Indices]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Algolia Index]}}" + }, + "variables": ["{{variables.[Algolia Index]}}"], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true + } + } + } + } + }, + { + "i": "dfa41039-1657-4142-b6a5-16ac7abffb9d", + "x": 1, + "y": 4, + "w": 2, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Search Volume", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[searchCount]}}", + "name": "searchCount", + "pluginConfigId": "{{configId}}", + "group": { + "by": [["date", "byDay"]], + "aggregate": [{ "type": "sum", "names": ["count"] }] + }, + "sort": { + "by": [["date_byDay", "asc"]] + } + }, + "scope": { + "scope": "{{scopes.[Algolia Indices]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Algolia Index]}}" + }, + "variables": ["{{variables.[Algolia Index]}}"], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date_byDay", + "yAxisColumn": ["count_sum"], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Searches", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "09cc7897-4e96-44b3-9205-144fcf3ef5fb", + "x": 4, + "y": 4, + "w": 4, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "No-Result Rate", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[noResultRate]}}", + "name": "noResultRate", + "pluginConfigId": "{{configId}}", + "group": { + "by": [["date", "byDay"]], + "aggregate": [{ "type": "mean", "names": ["rate"] }] + }, + "sort": { + "by": [["date_byDay", "asc"]] + } + }, + "scope": { + "scope": "{{scopes.[Algolia Indices]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Algolia Index]}}" + }, + "variables": ["{{variables.[Algolia Index]}}"], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date_byDay", + "yAxisColumn": ["rate_mean"], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "No-Result Rate", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "1c816936-aafc-42dc-8096-10f0281a6e17", + "x": 0, + "y": 0, + "w": 2, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Top Searches", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[topSearches]}}", + "name": "topSearches", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [["count", "desc"]] + } + }, + "scope": { + "scope": "{{scopes.[Algolia Indices]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Algolia Index]}}" + }, + "variables": ["{{variables.[Algolia Index]}}"], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": ["search", "count", "nbHits"] + } + } + } + } + }, + { + "i": "1727a100-9c88-41cb-b157-c0f197b1b13e", + "x": 2, + "y": 0, + "w": 2, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Searches With No Results", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[noResultSearches]}}", + "name": "noResultSearches", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [["count", "desc"]] + } + }, + "scope": { + "scope": "{{scopes.[Algolia Indices]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Algolia Index]}}" + }, + "variables": ["{{variables.[Algolia Index]}}"], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "search", + "count", + "withFilterCount" + ] + } + } + } + } + } + ] + } +} diff --git a/plugins/Algolia/v1/defaultContent/manifest.json b/plugins/Algolia/v1/defaultContent/manifest.json new file mode 100644 index 00000000..f1604d74 --- /dev/null +++ b/plugins/Algolia/v1/defaultContent/manifest.json @@ -0,0 +1,6 @@ +{ + "items": [ + { "name": "overview", "type": "dashboard" }, + { "name": "algoliaIndex", "type": "dashboard" } + ] +} diff --git a/plugins/Algolia/v1/defaultContent/overview.dash.json b/plugins/Algolia/v1/defaultContent/overview.dash.json new file mode 100644 index 00000000..37dee8ff --- /dev/null +++ b/plugins/Algolia/v1/defaultContent/overview.dash.json @@ -0,0 +1,209 @@ +{ + "name": "Overview", + "schemaVersion": "1.5", + "timeframe": "last24hours", + "variables": [], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "66e90a23-50f4-4e6b-b6b1-b8036378e1f7", + "x": 0, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Total Indices", + "description": "", + "timeframe": "none", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[indexes]}}", + "name": "indexes", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [{ "type": "count" }] + } + }, + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "count", + "comparisonColumn": "none", + "label": "Total Indices" + } + } + } + } + }, + { + "i": "08ad1e7c-f8c3-42b4-ab41-b8286aba64bc", + "x": 1, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Total Records", + "description": "", + "timeframe": "none", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[indexes]}}", + "name": "indexes", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [{ "type": "sum", "names": ["entries"] }] + } + }, + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "entries_sum", + "comparisonColumn": "none", + "label": "Total Records" + } + } + } + } + }, + { + "i": "a6b32024-6bee-4b5c-9b64-40baea590938", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Total Data Size", + "description": "", + "timeframe": "none", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[indexes]}}", + "name": "indexes", + "pluginConfigId": "{{configId}}", + "group": { + "by": [], + "aggregate": [{ "type": "sum", "names": ["dataSize"] }] + } + }, + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "dataSize_sum", + "comparisonColumn": "none", + "label": "Total Data Size (bytes)" + } + } + } + } + }, + { + "i": "6d24028f-a3dd-44f1-93dd-417a1c4e9863", + "x": 0, + "y": 2, + "w": 2, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Top Indices by Records", + "description": "", + "timeframe": "none", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[indexes]}}", + "name": "indexes", + "pluginConfigId": "{{configId}}", + "group": { + "by": [["name", "uniqueValues"]], + "aggregate": [{ "type": "sum", "names": ["entries"] }] + }, + "sort": { + "by": [["entries_sum", "desc"]], + "top": 10 + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "name_uniqueValues", + "yAxisData": ["entries_sum"], + "xAxisGroup": "none", + "xAxisLabel": "", + "yAxisLabel": "Records", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { "type": "auto" } + } + } + } + } + }, + { + "i": "55b48169-658b-44ca-85a3-3329fc59aa56", + "x": 2, + "y": 2, + "w": 2, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "All Indices", + "description": "", + "timeframe": "none", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[indexes]}}", + "name": "indexes", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [["entries", "desc"]] + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": ["name", "entries", "dataSize", "fileSize", "lastBuildTimeS", "numberOfPendingTasks"], + "hiddenColumns": ["pendingTask", "updatedAt", "primary"] + } + } + } + } + } + ] + } +} diff --git a/plugins/Algolia/v1/defaultContent/scopes.json b/plugins/Algolia/v1/defaultContent/scopes.json new file mode 100644 index 00000000..1690758a --- /dev/null +++ b/plugins/Algolia/v1/defaultContent/scopes.json @@ -0,0 +1,14 @@ +[ + { + "name": "Algolia Indices", + "matches": { + "sourceType": { "type": "oneOf", "values": ["Algolia Index"] } + }, + "variable": { + "name": "Algolia Index", + "allowMultipleSelection": false, + "default": "none", + "type": "object" + } + } +] diff --git a/plugins/Algolia/v1/docs/README.md b/plugins/Algolia/v1/docs/README.md new file mode 100644 index 00000000..ca44dc83 --- /dev/null +++ b/plugins/Algolia/v1/docs/README.md @@ -0,0 +1,52 @@ +# Algolia + +Monitor your [Algolia](https://www.algolia.com/) search application from SquaredUp. This plugin imports your Algolia **indices** as objects and provides dashboards covering index size and growth, search volume, and search quality (no-result rate, top searches). + +## What this plugin monitors + +- **Indices** — every index in your Algolia application is imported as an object, with its record count, data/file size, last build time and pending-task count. +- **Search analytics** (per index) — search volume over time, the no-results rate, your most popular searches, and the searches that returned no results. + +Out of the box you get an **Overview** dashboard (totals and top indices across the whole application) and an **Algolia Index** perspective (per-index size, search volume, and search-quality tiles). + +## Prerequisites — getting your credentials + +You need two values from the Algolia dashboard: your **Application ID** and an **API key**. + +1. Sign in to the [Algolia dashboard](https://dashboard.algolia.com/). +2. Go to **Settings → API Keys** (or **Account → API Keys**). +3. Copy your **Application ID** (shown at the top of the API Keys page — a short string like `LIxxxxxxxx`). +4. For the API key, use your **Admin API Key**, **or** (recommended) create a dedicated key with only the permissions this plugin needs. Click **All API keys → New API Key** and grant these ACLs: + - `listIndexes` — to import your indices + - `settings` — to read index configuration + - `analytics` — to read Search Analytics + - Leave **Indices** set to *all* (or restrict to the indices you want to monitor). + + A read-only **Search-Only API Key** is **not** sufficient — it lacks `listIndexes` and `analytics`. + +> **Tip:** Using a scoped custom key rather than your Admin key follows least-privilege best practice and means the key can be rotated without affecting other integrations. + +## Configuration fields + +| Field | Required | What it is / where to find it | +| --- | --- | --- | +| **Application ID** | Yes | Your Algolia Application ID, from **Settings → API Keys** in the Algolia dashboard. Also forms your API host (`https://.algolia.net`). | +| **API Key** | Yes | An Admin key, or a custom key with the `listIndexes`, `settings` and `analytics` ACLs (see above). Stored encrypted. | +| **Analytics region** | No (default **US**) | The region your Algolia app's analytics data is stored in. Choose **EU** only if your application was created in Algolia's EU (Germany) region — otherwise analytics tiles will be empty. Defaults to US. | + +## What gets indexed + +| Object type | Represents | Key properties | +| --- | --- | --- | +| **Algolia Index** | A single search index in your application | Records (entries), data size, file size, last build time (s), number of pending tasks, pending-task flag, last updated, primary index (for replicas) | + +Each index's object ID is its index name, which is unique within an application. + +## Known limitations + +- **Search Analytics only.** This version covers the Search and Search Analytics APIs. It does **not** include the **Usage API** (operations/records time series) or the **Monitoring API** (latency, indexing time, infrastructure metrics) — those require an Algolia **Premium/Enterprise** plan and dedicated Usage/Monitoring API keys. +- **Analytics granularity is daily.** Algolia's Search Analytics aggregates per calendar day, so the analytics tiles use timeframes of **7 days and longer**. Shorter timeframes (e.g. last hour) are not meaningful for this data. +- **Analytics need search traffic.** Indices with no recent search activity will show empty analytics tiles — this is expected, not an error. +- **Analytics region matters.** If your app is in Algolia's EU region but the plugin is left on the US analytics region (or vice-versa), analytics calls succeed but return no data. Set the **Analytics region** field to match your app. +- **Rate limits.** The Analytics API is limited to ~100 requests/minute per application; very large numbers of indices on a single dashboard may be throttled. +- **`listIndexes` required.** If you authenticate with a Search-Only key, setup validation will fail because the key cannot list indices. diff --git a/plugins/Algolia/v1/icon.svg b/plugins/Algolia/v1/icon.svg new file mode 100644 index 00000000..2101a202 --- /dev/null +++ b/plugins/Algolia/v1/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/plugins/Algolia/v1/indexDefinitions/default.json b/plugins/Algolia/v1/indexDefinitions/default.json new file mode 100644 index 00000000..8210458c --- /dev/null +++ b/plugins/Algolia/v1/indexDefinitions/default.json @@ -0,0 +1,24 @@ +{ + "steps": [ + { + "name": "indexes", + "dataStream": { "name": "indexes" }, + "timeframe": "none", + "objectMapping": { + "id": "name", + "name": "name", + "type": { "value": "Algolia Index" }, + "properties": [ + "entries", + "dataSize", + "fileSize", + "lastBuildTimeS", + "numberOfPendingTasks", + "pendingTask", + "updatedAt", + "primary" + ] + } + } + ] +} diff --git a/plugins/Algolia/v1/metadata.json b/plugins/Algolia/v1/metadata.json new file mode 100644 index 00000000..a76934e6 --- /dev/null +++ b/plugins/Algolia/v1/metadata.json @@ -0,0 +1,39 @@ +{ + "name": "algolia", + "displayName": "Algolia", + "version": "1.0.0", + "author": { "name": "Andrew Harris", "type": "community" }, + "description": "Monitor your Algolia search application — import indices and track index size, search volume, and search quality (no-result rate, top searches).", + "category": "Monitoring", + "type": "hybrid", + "schemaVersion": "2.1", + "importNotSupported": false, + "restrictedToPlatforms": [], + "keywords": ["algolia", "search", "analytics", "index", "search analytics"], + "objectTypes": ["Algolia Index"], + "links": [ + { + "category": "documentation", + "url": "https://github.com/squaredup/plugins/blob/main/plugins/Algolia/v1/docs/README.md", + "label": "Help adding this plugin" + }, + { + "category": "source", + "url": "https://github.com/squaredup/plugins/tree/main/plugins/Algolia/v1", + "label": "Repository" + } + ], + "base": { + "plugin": "WebAPI", + "majorVersion": "1", + "config": { + "baseUrl": "https://{{applicationId}}.algolia.net", + "authMode": "none", + "headers": [ + { "key": "X-Algolia-Application-Id", "value": "{{applicationId}}" }, + { "key": "X-Algolia-API-Key", "value": "{{apiKey}}" } + ], + "queryArgs": [] + } + } +} diff --git a/plugins/Algolia/v1/ui.json b/plugins/Algolia/v1/ui.json new file mode 100644 index 00000000..175a2a5b --- /dev/null +++ b/plugins/Algolia/v1/ui.json @@ -0,0 +1,28 @@ +[ + { + "type": "text", + "name": "applicationId", + "label": "Application ID", + "placeholder": "e.g. LIXXXXXXXX", + "help": "Your Algolia Application ID, found under **Settings → API Keys** in the Algolia dashboard. This also forms your API host (`https://.algolia.net`).", + "validation": { "required": true } + }, + { + "type": "password", + "name": "apiKey", + "label": "API Key", + "help": "An Algolia **Admin API Key**, or a custom key with the `listIndexes`, `settings` and `analytics` ACLs. A Search-Only key will not work. Found under **Settings → API Keys**.", + "validation": { "required": true } + }, + { + "type": "switch", + "name": "analyticsRegion", + "label": "Analytics region", + "defaultValue": "us", + "options": [ + { "value": "us", "label": "US" }, + { "value": "de", "label": "EU" } + ], + "help": "The region your Algolia application's analytics data is stored in. Choose **EU** only if your application was created in Algolia's EU (Germany) region; otherwise leave as **US**. The wrong region returns empty analytics." + } +] From bf3bee8bb2c681c6cbfac91542f70e134d2a9947 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Tue, 16 Jun 2026 16:39:27 +0100 Subject: [PATCH 02/19] Update Algolia icon --- .../v1/defaultContent/overview.dash.json | 29 +++++++++++++++---- plugins/Algolia/v1/icon.svg | 8 ++--- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/plugins/Algolia/v1/defaultContent/overview.dash.json b/plugins/Algolia/v1/defaultContent/overview.dash.json index 37dee8ff..969e77b4 100644 --- a/plugins/Algolia/v1/defaultContent/overview.dash.json +++ b/plugins/Algolia/v1/defaultContent/overview.dash.json @@ -65,7 +65,9 @@ "pluginConfigId": "{{configId}}", "group": { "by": [], - "aggregate": [{ "type": "sum", "names": ["entries"] }] + "aggregate": [ + { "type": "sum", "names": ["entries"] } + ] } }, "visualisation": { @@ -101,7 +103,9 @@ "pluginConfigId": "{{configId}}", "group": { "by": [], - "aggregate": [{ "type": "sum", "names": ["dataSize"] }] + "aggregate": [ + { "type": "sum", "names": ["dataSize"] } + ] } }, "visualisation": { @@ -110,7 +114,7 @@ "data-stream-scalar": { "value": "dataSize_sum", "comparisonColumn": "none", - "label": "Total Data Size (bytes)" + "label": "Total Data Size" } } } @@ -137,7 +141,9 @@ "pluginConfigId": "{{configId}}", "group": { "by": [["name", "uniqueValues"]], - "aggregate": [{ "type": "sum", "names": ["entries"] }] + "aggregate": [ + { "type": "sum", "names": ["entries"] } + ] }, "sort": { "by": [["entries_sum", "desc"]], @@ -197,8 +203,19 @@ "config": { "data-stream-table": { "transpose": false, - "columnOrder": ["name", "entries", "dataSize", "fileSize", "lastBuildTimeS", "numberOfPendingTasks"], - "hiddenColumns": ["pendingTask", "updatedAt", "primary"] + "columnOrder": [ + "name", + "entries", + "dataSize", + "fileSize", + "lastBuildTimeS", + "numberOfPendingTasks" + ], + "hiddenColumns": [ + "pendingTask", + "updatedAt", + "primary" + ] } } } diff --git a/plugins/Algolia/v1/icon.svg b/plugins/Algolia/v1/icon.svg index 2101a202..95311981 100644 --- a/plugins/Algolia/v1/icon.svg +++ b/plugins/Algolia/v1/icon.svg @@ -1,6 +1,4 @@ - - - - - + + + From f4724ba021b1f71a038fab65906355dd6adbfeb7 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Tue, 16 Jun 2026 16:41:49 +0100 Subject: [PATCH 03/19] tweak algolia icon alignment --- plugins/Algolia/v1/icon.svg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Algolia/v1/icon.svg b/plugins/Algolia/v1/icon.svg index 95311981..ab64fef5 100644 --- a/plugins/Algolia/v1/icon.svg +++ b/plugins/Algolia/v1/icon.svg @@ -1,4 +1,4 @@ - - - + + + From 2eb7ac7eb3297d7b09400be10fd1cd540a2467f8 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Tue, 16 Jun 2026 16:44:15 +0100 Subject: [PATCH 04/19] fix algoliaIndex tile sizing and placement --- plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json b/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json index 708e2851..0d9a8761 100644 --- a/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json +++ b/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json @@ -45,7 +45,7 @@ }, { "i": "dfa41039-1657-4142-b6a5-16ac7abffb9d", - "x": 1, + "x": 0, "y": 4, "w": 2, "h": 4, @@ -94,9 +94,9 @@ }, { "i": "09cc7897-4e96-44b3-9205-144fcf3ef5fb", - "x": 4, + "x": 2, "y": 4, - "w": 4, + "w": 2, "h": 4, "moved": false, "static": false, From 25cca2bdff1486555506b08942285a17bda581a3 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Thu, 18 Jun 2026 06:55:01 +0100 Subject: [PATCH 05/19] Swap baseUrl for Algolia plugin dataStreams to reduce duplication --- plugins/Algolia/v1/dataStreams/indexes.json | 3 ++- plugins/Algolia/v1/dataStreams/noResultRate.json | 4 ++-- .../Algolia/v1/dataStreams/noResultSearches.json | 1 - plugins/Algolia/v1/dataStreams/searchCount.json | 1 - plugins/Algolia/v1/dataStreams/topSearches.json | 1 - plugins/Algolia/v1/metadata.json | 9 ++++++--- plugins/Algolia/v1/ui.json | 15 +++++++++++++++ 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/plugins/Algolia/v1/dataStreams/indexes.json b/plugins/Algolia/v1/dataStreams/indexes.json index fa708784..b99995ab 100644 --- a/plugins/Algolia/v1/dataStreams/indexes.json +++ b/plugins/Algolia/v1/dataStreams/indexes.json @@ -5,8 +5,9 @@ "tags": [], "baseDataSourceName": "httpRequestUnscoped", "config": { + "baseUrl": "https://{{dataSource.applicationId}}.algolia.net", "httpMethod": "get", - "endpointPath": "1/indexes", + "endpointPath": "/1/indexes", "pathToData": "items", "paging": { "mode": "none" } }, diff --git a/plugins/Algolia/v1/dataStreams/noResultRate.json b/plugins/Algolia/v1/dataStreams/noResultRate.json index a4175387..c735c761 100644 --- a/plugins/Algolia/v1/dataStreams/noResultRate.json +++ b/plugins/Algolia/v1/dataStreams/noResultRate.json @@ -6,12 +6,12 @@ "baseDataSourceName": "httpRequestScopedSingle", "config": { "httpMethod": "get", - "baseUrl": "https://analytics.{{dataSource.analyticsRegion || 'us'}}.algolia.com", "endpointPath": "/2/searches/noResultRate", "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, - { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" } + { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" }, + { "key": "test", "value": "{{dataSource.analyticsRegion}}" } ], "pathToData": "dates" }, diff --git a/plugins/Algolia/v1/dataStreams/noResultSearches.json b/plugins/Algolia/v1/dataStreams/noResultSearches.json index e65a98a2..b9276906 100644 --- a/plugins/Algolia/v1/dataStreams/noResultSearches.json +++ b/plugins/Algolia/v1/dataStreams/noResultSearches.json @@ -6,7 +6,6 @@ "baseDataSourceName": "httpRequestScopedSingle", "config": { "httpMethod": "get", - "baseUrl": "https://analytics.{{dataSource.analyticsRegion || 'us'}}.algolia.com", "endpointPath": "/2/searches/noResults", "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, diff --git a/plugins/Algolia/v1/dataStreams/searchCount.json b/plugins/Algolia/v1/dataStreams/searchCount.json index 7d4dca26..ff2c422b 100644 --- a/plugins/Algolia/v1/dataStreams/searchCount.json +++ b/plugins/Algolia/v1/dataStreams/searchCount.json @@ -6,7 +6,6 @@ "baseDataSourceName": "httpRequestScopedSingle", "config": { "httpMethod": "get", - "baseUrl": "https://analytics.{{dataSource.analyticsRegion || 'us'}}.algolia.com", "endpointPath": "/2/searches/count", "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, diff --git a/plugins/Algolia/v1/dataStreams/topSearches.json b/plugins/Algolia/v1/dataStreams/topSearches.json index 1c8c1878..690ea1b4 100644 --- a/plugins/Algolia/v1/dataStreams/topSearches.json +++ b/plugins/Algolia/v1/dataStreams/topSearches.json @@ -6,7 +6,6 @@ "baseDataSourceName": "httpRequestScopedSingle", "config": { "httpMethod": "get", - "baseUrl": "https://analytics.{{dataSource.analyticsRegion || 'us'}}.algolia.com", "endpointPath": "/2/searches", "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, diff --git a/plugins/Algolia/v1/metadata.json b/plugins/Algolia/v1/metadata.json index a76934e6..d8528db3 100644 --- a/plugins/Algolia/v1/metadata.json +++ b/plugins/Algolia/v1/metadata.json @@ -2,7 +2,7 @@ "name": "algolia", "displayName": "Algolia", "version": "1.0.0", - "author": { "name": "Andrew Harris", "type": "community" }, + "author": { "name": "@andrewmumblebee", "type": "community" }, "description": "Monitor your Algolia search application — import indices and track index size, search volume, and search quality (no-result rate, top searches).", "category": "Monitoring", "type": "hybrid", @@ -27,10 +27,13 @@ "plugin": "WebAPI", "majorVersion": "1", "config": { - "baseUrl": "https://{{applicationId}}.algolia.net", + "baseUrl": "https://analytics.{{analyticsRegion}}.algolia.com", "authMode": "none", "headers": [ - { "key": "X-Algolia-Application-Id", "value": "{{applicationId}}" }, + { + "key": "X-Algolia-Application-Id", + "value": "{{applicationId}}" + }, { "key": "X-Algolia-API-Key", "value": "{{apiKey}}" } ], "queryArgs": [] diff --git a/plugins/Algolia/v1/ui.json b/plugins/Algolia/v1/ui.json index 175a2a5b..838b54a3 100644 --- a/plugins/Algolia/v1/ui.json +++ b/plugins/Algolia/v1/ui.json @@ -24,5 +24,20 @@ { "value": "de", "label": "EU" } ], "help": "The region your Algolia application's analytics data is stored in. Choose **EU** only if your application was created in Algolia's EU (Germany) region; otherwise leave as **US**. The wrong region returns empty analytics." + }, + { + "type": "key-value", + "name": "projectKeys", + "label": "Project Keys", + "verb": ":", + "keyInput": { + "title": "projectId", + "placeholder": "projectId" + }, + "valueInput": { + "title": "apiKey", + "placeholder": "apiKey" + }, + "allowEncryption": true } ] From 6ef8027c38748bfdd3fe873b724076ef0f07d5a2 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Thu, 18 Jun 2026 07:06:38 +0100 Subject: [PATCH 06/19] Remove test edits and add tags --- plugins/Algolia/v1/dataStreams/indexes.json | 4 ++-- plugins/Algolia/v1/dataStreams/noResultRate.json | 5 ++--- .../Algolia/v1/dataStreams/noResultSearches.json | 2 +- plugins/Algolia/v1/dataStreams/searchCount.json | 2 +- plugins/Algolia/v1/dataStreams/topSearches.json | 2 +- plugins/Algolia/v1/ui.json | 15 --------------- 6 files changed, 7 insertions(+), 23 deletions(-) diff --git a/plugins/Algolia/v1/dataStreams/indexes.json b/plugins/Algolia/v1/dataStreams/indexes.json index b99995ab..7dfe23c3 100644 --- a/plugins/Algolia/v1/dataStreams/indexes.json +++ b/plugins/Algolia/v1/dataStreams/indexes.json @@ -1,8 +1,8 @@ { "name": "indexes", "displayName": "Indices", - "description": "Algolia indices in the application, with record counts, sizes, last build time and pending tasks.", - "tags": [], + "description": "Algolia indices in the application, with record counts, sizes, last build time and pending tasks", + "tags": ["Indices"], "baseDataSourceName": "httpRequestUnscoped", "config": { "baseUrl": "https://{{dataSource.applicationId}}.algolia.net", diff --git a/plugins/Algolia/v1/dataStreams/noResultRate.json b/plugins/Algolia/v1/dataStreams/noResultRate.json index c735c761..4061e3b5 100644 --- a/plugins/Algolia/v1/dataStreams/noResultRate.json +++ b/plugins/Algolia/v1/dataStreams/noResultRate.json @@ -2,7 +2,7 @@ "name": "noResultRate", "displayName": "No-Result Rate", "description": "Daily proportion of searches returning no results for an index", - "tags": [], + "tags": ["Analytics"], "baseDataSourceName": "httpRequestScopedSingle", "config": { "httpMethod": "get", @@ -10,8 +10,7 @@ "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, - { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" }, - { "key": "test", "value": "{{dataSource.analyticsRegion}}" } + { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" } ], "pathToData": "dates" }, diff --git a/plugins/Algolia/v1/dataStreams/noResultSearches.json b/plugins/Algolia/v1/dataStreams/noResultSearches.json index b9276906..d260896e 100644 --- a/plugins/Algolia/v1/dataStreams/noResultSearches.json +++ b/plugins/Algolia/v1/dataStreams/noResultSearches.json @@ -2,7 +2,7 @@ "name": "noResultSearches", "displayName": "Top Searches With No Results", "description": "Most frequent searches that returned no results for an index", - "tags": [], + "tags": ["Analytics"], "baseDataSourceName": "httpRequestScopedSingle", "config": { "httpMethod": "get", diff --git a/plugins/Algolia/v1/dataStreams/searchCount.json b/plugins/Algolia/v1/dataStreams/searchCount.json index ff2c422b..76a33265 100644 --- a/plugins/Algolia/v1/dataStreams/searchCount.json +++ b/plugins/Algolia/v1/dataStreams/searchCount.json @@ -2,7 +2,7 @@ "name": "searchCount", "displayName": "Search Count", "description": "Daily number of searches for an index over the selected timeframe", - "tags": [], + "tags": ["Analytics"], "baseDataSourceName": "httpRequestScopedSingle", "config": { "httpMethod": "get", diff --git a/plugins/Algolia/v1/dataStreams/topSearches.json b/plugins/Algolia/v1/dataStreams/topSearches.json index 690ea1b4..6526ca9a 100644 --- a/plugins/Algolia/v1/dataStreams/topSearches.json +++ b/plugins/Algolia/v1/dataStreams/topSearches.json @@ -2,7 +2,7 @@ "name": "topSearches", "displayName": "Top Searches", "description": "Most frequent search queries for an index over the selected timeframe", - "tags": [], + "tags": ["Analytics"], "baseDataSourceName": "httpRequestScopedSingle", "config": { "httpMethod": "get", diff --git a/plugins/Algolia/v1/ui.json b/plugins/Algolia/v1/ui.json index 838b54a3..175a2a5b 100644 --- a/plugins/Algolia/v1/ui.json +++ b/plugins/Algolia/v1/ui.json @@ -24,20 +24,5 @@ { "value": "de", "label": "EU" } ], "help": "The region your Algolia application's analytics data is stored in. Choose **EU** only if your application was created in Algolia's EU (Germany) region; otherwise leave as **US**. The wrong region returns empty analytics." - }, - { - "type": "key-value", - "name": "projectKeys", - "label": "Project Keys", - "verb": ":", - "keyInput": { - "title": "projectId", - "placeholder": "projectId" - }, - "valueInput": { - "title": "apiKey", - "placeholder": "apiKey" - }, - "allowEncryption": true } ] From e4473e555a9156f4f69bfbdd4e05ccc46bda8434 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Thu, 18 Jun 2026 09:49:01 +0100 Subject: [PATCH 07/19] Rename Algolia sourceType to Index as per guidelines --- plugins/Algolia/v1/custom_types.json | 4 ++-- plugins/Algolia/v1/dataStreams/noResultRate.json | 2 +- plugins/Algolia/v1/dataStreams/noResultSearches.json | 2 +- plugins/Algolia/v1/dataStreams/searchCount.json | 2 +- plugins/Algolia/v1/dataStreams/topSearches.json | 2 +- plugins/Algolia/v1/defaultContent/scopes.json | 2 +- plugins/Algolia/v1/indexDefinitions/default.json | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/Algolia/v1/custom_types.json b/plugins/Algolia/v1/custom_types.json index 2ad28542..845c2dd0 100644 --- a/plugins/Algolia/v1/custom_types.json +++ b/plugins/Algolia/v1/custom_types.json @@ -1,7 +1,7 @@ [ { - "name": "Algolia Index", - "sourceType": "Algolia Index", + "name": "Index", + "sourceType": "Index", "icon": "magnifying-glass", "singular": "Index", "plural": "Indices" diff --git a/plugins/Algolia/v1/dataStreams/noResultRate.json b/plugins/Algolia/v1/dataStreams/noResultRate.json index 4061e3b5..9c10f388 100644 --- a/plugins/Algolia/v1/dataStreams/noResultRate.json +++ b/plugins/Algolia/v1/dataStreams/noResultRate.json @@ -14,7 +14,7 @@ ], "pathToData": "dates" }, - "matches": { "sourceType": { "type": "equals", "value": "Algolia Index" } }, + "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ { "name": "date", diff --git a/plugins/Algolia/v1/dataStreams/noResultSearches.json b/plugins/Algolia/v1/dataStreams/noResultSearches.json index d260896e..6fc50e53 100644 --- a/plugins/Algolia/v1/dataStreams/noResultSearches.json +++ b/plugins/Algolia/v1/dataStreams/noResultSearches.json @@ -16,7 +16,7 @@ "pathToData": "searches", "paging": { "mode": "none" } }, - "matches": { "sourceType": { "type": "equals", "value": "Algolia Index" } }, + "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ { "name": "search", diff --git a/plugins/Algolia/v1/dataStreams/searchCount.json b/plugins/Algolia/v1/dataStreams/searchCount.json index 76a33265..30277feb 100644 --- a/plugins/Algolia/v1/dataStreams/searchCount.json +++ b/plugins/Algolia/v1/dataStreams/searchCount.json @@ -14,7 +14,7 @@ ], "pathToData": "dates" }, - "matches": { "sourceType": { "type": "equals", "value": "Algolia Index" } }, + "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ { "name": "date", diff --git a/plugins/Algolia/v1/dataStreams/topSearches.json b/plugins/Algolia/v1/dataStreams/topSearches.json index 6526ca9a..15d4766c 100644 --- a/plugins/Algolia/v1/dataStreams/topSearches.json +++ b/plugins/Algolia/v1/dataStreams/topSearches.json @@ -16,7 +16,7 @@ "pathToData": "searches", "paging": { "mode": "none" } }, - "matches": { "sourceType": { "type": "equals", "value": "Algolia Index" } }, + "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ { "name": "search", diff --git a/plugins/Algolia/v1/defaultContent/scopes.json b/plugins/Algolia/v1/defaultContent/scopes.json index 1690758a..3a3c95be 100644 --- a/plugins/Algolia/v1/defaultContent/scopes.json +++ b/plugins/Algolia/v1/defaultContent/scopes.json @@ -2,7 +2,7 @@ { "name": "Algolia Indices", "matches": { - "sourceType": { "type": "oneOf", "values": ["Algolia Index"] } + "sourceType": { "type": "oneOf", "values": ["Index"] } }, "variable": { "name": "Algolia Index", diff --git a/plugins/Algolia/v1/indexDefinitions/default.json b/plugins/Algolia/v1/indexDefinitions/default.json index 8210458c..241577f1 100644 --- a/plugins/Algolia/v1/indexDefinitions/default.json +++ b/plugins/Algolia/v1/indexDefinitions/default.json @@ -7,7 +7,7 @@ "objectMapping": { "id": "name", "name": "name", - "type": { "value": "Algolia Index" }, + "type": { "value": "Index" }, "properties": [ "entries", "dataSize", From 24ddd4ecf06bbf4448b2713aaffa791d4c2f1bb9 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Thu, 18 Jun 2026 09:55:14 +0100 Subject: [PATCH 08/19] Add algolia codeowner --- .github/CODEOWNERS | 1 + plugins/Algolia/v1/dataStreams/indexes.json | 2 +- plugins/Algolia/v1/docs/README.md | 26 ++++++++++----------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9690e211..932be760 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -24,6 +24,7 @@ plugins/TransportForLondon/* @clarkd plugins/UniFi/* @adamkinniburgh plugins/UptimeRobot/* @kieranlangton plugins/WorldCup2026/* @TimWheeler-SQUP +plugins/Algolia/* @andrewmumblebee # Fallback – if a plugin has no specified author diff --git a/plugins/Algolia/v1/dataStreams/indexes.json b/plugins/Algolia/v1/dataStreams/indexes.json index 7dfe23c3..04c52579 100644 --- a/plugins/Algolia/v1/dataStreams/indexes.json +++ b/plugins/Algolia/v1/dataStreams/indexes.json @@ -40,7 +40,7 @@ "shape": ["number", { "decimalPlaces": 0 }] }, { "name": "pendingTask", "displayName": "Has Pending Task" }, - { "name": "updatedAt", "displayName": "Last Updated" }, + { "name": "updatedAt", "displayName": "Last Updated", "shape": "date" }, { "name": "primary", "displayName": "Primary Index" } ], "timeframes": false diff --git a/plugins/Algolia/v1/docs/README.md b/plugins/Algolia/v1/docs/README.md index ca44dc83..43aae67c 100644 --- a/plugins/Algolia/v1/docs/README.md +++ b/plugins/Algolia/v1/docs/README.md @@ -1,9 +1,7 @@ -# Algolia +## What this plugin monitors Monitor your [Algolia](https://www.algolia.com/) search application from SquaredUp. This plugin imports your Algolia **indices** as objects and provides dashboards covering index size and growth, search volume, and search quality (no-result rate, top searches). -## What this plugin monitors - - **Indices** — every index in your Algolia application is imported as an object, with its record count, data/file size, last build time and pending-task count. - **Search analytics** (per index) — search volume over time, the no-results rate, your most popular searches, and the searches that returned no results. @@ -17,27 +15,27 @@ You need two values from the Algolia dashboard: your **Application ID** and an * 2. Go to **Settings → API Keys** (or **Account → API Keys**). 3. Copy your **Application ID** (shown at the top of the API Keys page — a short string like `LIxxxxxxxx`). 4. For the API key, use your **Admin API Key**, **or** (recommended) create a dedicated key with only the permissions this plugin needs. Click **All API keys → New API Key** and grant these ACLs: - - `listIndexes` — to import your indices - - `settings` — to read index configuration - - `analytics` — to read Search Analytics - - Leave **Indices** set to *all* (or restrict to the indices you want to monitor). + - `listIndexes` — to import your indices + - `settings` — to read index configuration + - `analytics` — to read Search Analytics + - Leave **Indices** set to _all_ (or restrict to the indices you want to monitor). - A read-only **Search-Only API Key** is **not** sufficient — it lacks `listIndexes` and `analytics`. + A read-only **Search-Only API Key** is **not** sufficient — it lacks `listIndexes` and `analytics`. > **Tip:** Using a scoped custom key rather than your Admin key follows least-privilege best practice and means the key can be rotated without affecting other integrations. ## Configuration fields -| Field | Required | What it is / where to find it | -| --- | --- | --- | -| **Application ID** | Yes | Your Algolia Application ID, from **Settings → API Keys** in the Algolia dashboard. Also forms your API host (`https://.algolia.net`). | -| **API Key** | Yes | An Admin key, or a custom key with the `listIndexes`, `settings` and `analytics` ACLs (see above). Stored encrypted. | +| Field | Required | What it is / where to find it | +| -------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Application ID** | Yes | Your Algolia Application ID, from **Settings → API Keys** in the Algolia dashboard. Also forms your API host (`https://.algolia.net`). | +| **API Key** | Yes | An Admin key, or a custom key with the `listIndexes`, `settings` and `analytics` ACLs (see above). Stored encrypted. | | **Analytics region** | No (default **US**) | The region your Algolia app's analytics data is stored in. Choose **EU** only if your application was created in Algolia's EU (Germany) region — otherwise analytics tiles will be empty. Defaults to US. | ## What gets indexed -| Object type | Represents | Key properties | -| --- | --- | --- | +| Object type | Represents | Key properties | +| ----------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | **Algolia Index** | A single search index in your application | Records (entries), data size, file size, last build time (s), number of pending tasks, pending-task flag, last updated, primary index (for replicas) | Each index's object ID is its index name, which is unique within an application. From d072d8766e71f52eb714b170917f4382511989bc Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Thu, 18 Jun 2026 11:40:31 +0100 Subject: [PATCH 09/19] Update object types --- plugins/Algolia/v1/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Algolia/v1/metadata.json b/plugins/Algolia/v1/metadata.json index d8528db3..5d4eb8d0 100644 --- a/plugins/Algolia/v1/metadata.json +++ b/plugins/Algolia/v1/metadata.json @@ -10,7 +10,7 @@ "importNotSupported": false, "restrictedToPlatforms": [], "keywords": ["algolia", "search", "analytics", "index", "search analytics"], - "objectTypes": ["Algolia Index"], + "objectTypes": ["Index"], "links": [ { "category": "documentation", From d83f3fed7590175802f8791a57b89f20c9264a9d Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Fri, 19 Jun 2026 10:31:07 +0100 Subject: [PATCH 10/19] Add scripts to include index in scoped dataStreams --- plugins/Algolia/v1/dataStreams/noResultRate.json | 2 +- plugins/Algolia/v1/dataStreams/noResultSearches.json | 8 +++++++- plugins/Algolia/v1/dataStreams/scripts/datesAddIndex.js | 8 ++++++++ plugins/Algolia/v1/dataStreams/scripts/searchAddIndex.js | 8 ++++++++ plugins/Algolia/v1/dataStreams/searchCount.json | 8 +++++++- plugins/Algolia/v1/dataStreams/topSearches.json | 2 +- 6 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 plugins/Algolia/v1/dataStreams/scripts/datesAddIndex.js create mode 100644 plugins/Algolia/v1/dataStreams/scripts/searchAddIndex.js diff --git a/plugins/Algolia/v1/dataStreams/noResultRate.json b/plugins/Algolia/v1/dataStreams/noResultRate.json index 9c10f388..020c6434 100644 --- a/plugins/Algolia/v1/dataStreams/noResultRate.json +++ b/plugins/Algolia/v1/dataStreams/noResultRate.json @@ -12,7 +12,7 @@ { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" } ], - "pathToData": "dates" + "postRequestScript": "datesAddIndex.js" }, "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ diff --git a/plugins/Algolia/v1/dataStreams/noResultSearches.json b/plugins/Algolia/v1/dataStreams/noResultSearches.json index 6fc50e53..2d364bf7 100644 --- a/plugins/Algolia/v1/dataStreams/noResultSearches.json +++ b/plugins/Algolia/v1/dataStreams/noResultSearches.json @@ -13,11 +13,17 @@ { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" }, { "key": "limit", "value": "50" } ], - "pathToData": "searches", + "postRequestScript": "searchAddIndex.js", "paging": { "mode": "none" } }, "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ + { + "name": "index", + "displayName": "Index", + "shape": "string", + "role": "id" + }, { "name": "search", "displayName": "Search", diff --git a/plugins/Algolia/v1/dataStreams/scripts/datesAddIndex.js b/plugins/Algolia/v1/dataStreams/scripts/datesAddIndex.js new file mode 100644 index 00000000..6c9f6131 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/scripts/datesAddIndex.js @@ -0,0 +1,8 @@ +// Add the index name to allow grouping +var object = context.objects[0]; +result = + data?.dates?.map((r) => ({ + ...r, + index: object.rawId, + })) ?? []; + diff --git a/plugins/Algolia/v1/dataStreams/scripts/searchAddIndex.js b/plugins/Algolia/v1/dataStreams/scripts/searchAddIndex.js new file mode 100644 index 00000000..e9ea0197 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/scripts/searchAddIndex.js @@ -0,0 +1,8 @@ +// Add the index name to allow grouping +var object = context.objects[0]; +result = + data?.searches?.map((r) => ({ + ...r, + index: object.rawId, + })) ?? []; + diff --git a/plugins/Algolia/v1/dataStreams/searchCount.json b/plugins/Algolia/v1/dataStreams/searchCount.json index 30277feb..73214535 100644 --- a/plugins/Algolia/v1/dataStreams/searchCount.json +++ b/plugins/Algolia/v1/dataStreams/searchCount.json @@ -12,10 +12,16 @@ { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" } ], - "pathToData": "dates" + "postRequestScript": "datesAddIndex.js" }, "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ + { + "name": "index", + "displayName": "Index", + "shape": "string", + "role": "id" + }, { "name": "date", "displayName": "Date", diff --git a/plugins/Algolia/v1/dataStreams/topSearches.json b/plugins/Algolia/v1/dataStreams/topSearches.json index 15d4766c..c9d5c9b8 100644 --- a/plugins/Algolia/v1/dataStreams/topSearches.json +++ b/plugins/Algolia/v1/dataStreams/topSearches.json @@ -13,7 +13,7 @@ { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" }, { "key": "limit", "value": "50" } ], - "pathToData": "searches", + "postRequestScript": "searchAddIndex.js", "paging": { "mode": "none" } }, "matches": { "sourceType": { "type": "equals", "value": "Index" } }, From a0607bc203f06fb14cf7289b42230225c5ed4d22 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Fri, 19 Jun 2026 10:31:16 +0100 Subject: [PATCH 11/19] Rework overview dashboard --- .../v1/defaultContent/overview.dash.json | 158 +++++++++++++++--- 1 file changed, 134 insertions(+), 24 deletions(-) diff --git a/plugins/Algolia/v1/defaultContent/overview.dash.json b/plugins/Algolia/v1/defaultContent/overview.dash.json index 969e77b4..b243e04b 100644 --- a/plugins/Algolia/v1/defaultContent/overview.dash.json +++ b/plugins/Algolia/v1/defaultContent/overview.dash.json @@ -1,12 +1,12 @@ { "name": "Overview", "schemaVersion": "1.5", - "timeframe": "last24hours", + "timeframe": "last7days", "variables": [], "dashboard": { "_type": "layout/grid", + "version": 50, "columns": 4, - "version": 1, "contents": [ { "i": "66e90a23-50f4-4e6b-b6b1-b8036378e1f7", @@ -83,38 +83,44 @@ } }, { - "i": "a6b32024-6bee-4b5c-9b64-40baea590938", + "i": "c3f45e29-63aa-4d33-a4b8-1eab017dacf6", "x": 2, "y": 0, - "w": 1, - "h": 2, + "w": 2, + "h": 3, "moved": false, "static": false, "z": 0, "config": { "_type": "tile/data-stream", - "title": "Total Data Size", + "title": "Search Count", "description": "", - "timeframe": "none", "activePluginConfigIds": ["{{configId}}"], "dataStream": { - "id": "{{dataStreams.[indexes]}}", - "name": "indexes", - "pluginConfigId": "{{configId}}", + "id": "{{dataStreams.[searchCount]}}", + "name": "searchCount", "group": { - "by": [], + "by": [["index", "uniqueValues"]], "aggregate": [ - { "type": "sum", "names": ["dataSize"] } + { "type": "sum", "names": ["count"] } ] } }, + "scope": { + "query": "g.V().order().by('__name').hasNot('__canonicalType').has(\"__configId\", within(\"{{configId}}\")).or(__.has(\"sourceType\", \"Index\")).limit(500)", + "bindings": {}, + "queryDetail": {} + }, "visualisation": { - "type": "data-stream-scalar", + "type": "data-stream-donut-chart", "config": { - "data-stream-scalar": { - "value": "dataSize_sum", - "comparisonColumn": "none", - "label": "Total Data Size" + "data-stream-donut-chart": { + "valueColumn": "count_sum", + "labelColumn": "index_uniqueValues", + "legendMode": "inline", + "legendPosition": "auto", + "showValuesAsPercentage": false, + "hideCenterValue": false } } } @@ -125,7 +131,7 @@ "x": 0, "y": 2, "w": 2, - "h": 4, + "h": 3, "moved": false, "static": false, "z": 0, @@ -146,8 +152,8 @@ ] }, "sort": { - "by": [["entries_sum", "desc"]], - "top": 10 + "top": 10, + "by": [["entries_sum", "desc"]] } }, "visualisation": { @@ -166,10 +172,114 @@ "showGrid": true, "horizontalLayout": "vertical", "displayMode": "actual", - "showTotals": false, + "showTotals": true, "showValue": false, "grouping": false, - "range": { "type": "auto" } + "range": { "type": "auto" }, + "color": { "type": "default" } + } + } + } + } + }, + { + "i": "86409b9b-56a0-445b-b9d4-072c08567094", + "x": 2, + "y": 3, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Top 10 Searches", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[topSearches]}}", + "name": "topSearches", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "search", + "operation": "notempty" + } + ] + }, + "group": { + "by": [["search", "uniqueValues"]], + "aggregate": [ + { "type": "sum", "names": ["count"] } + ] + }, + "sort": { + "top": 10, + "by": [["count_sum", "desc"]] + } + }, + "scope": { + "query": "g.V().order().by('__name').hasNot('__canonicalType').has(\"__configId\", within(\"{{configId}}\")).or(__.has(\"sourceType\", \"Index\")).limit(500)", + "bindings": {}, + "queryDetail": {} + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": ["search_uniqueValues", "count_sum"], + "hiddenColumns": [] + } + } + } + } + }, + { + "i": "d8077738-aec5-49f0-bd1b-cf7cb8823ebe", + "x": 0, + "y": 5, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Search Volume", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "dataStream": { + "id": "{{dataStreams.[searchCount]}}", + "name": "searchCount", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "count", + "operation": "greaterthan", + "value": "0" + } + ] + } + }, + "scope": { + "query": "g.V().order().by('__name').hasNot('__canonicalType').has(\"__configId\", within(\"{{configId}}\")).or(__.has(\"sourceType\", \"Index\")).limit(500)", + "bindings": {}, + "queryDetail": {} + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": ["count"], + "seriesColumn": "index", + "showLegend": true, + "legendPosition": "bottom", + "dataPoints": false, + "showTrendLine": false, + "cumulative": false } } } @@ -178,9 +288,9 @@ { "i": "55b48169-658b-44ca-85a3-3329fc59aa56", "x": 2, - "y": 2, + "y": 6, "w": 2, - "h": 4, + "h": 2, "moved": false, "static": false, "z": 0, From f1c6431b4a0124f179e1ad2f00d0fe32e654e083 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Fri, 19 Jun 2026 10:32:10 +0100 Subject: [PATCH 12/19] Rename index perspective --- .../{algoliaIndex.dash.json => index.dash.json} | 2 +- plugins/Algolia/v1/defaultContent/manifest.json | 2 +- plugins/Algolia/v1/docs/README.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) rename plugins/Algolia/v1/defaultContent/{algoliaIndex.dash.json => index.dash.json} (99%) diff --git a/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json b/plugins/Algolia/v1/defaultContent/index.dash.json similarity index 99% rename from plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json rename to plugins/Algolia/v1/defaultContent/index.dash.json index 0d9a8761..6c542178 100644 --- a/plugins/Algolia/v1/defaultContent/algoliaIndex.dash.json +++ b/plugins/Algolia/v1/defaultContent/index.dash.json @@ -1,5 +1,5 @@ { - "name": "Algolia Index", + "name": "Index", "schemaVersion": "1.5", "timeframe": "last30days", "variables": ["{{variables.[Algolia Index]}}"], diff --git a/plugins/Algolia/v1/defaultContent/manifest.json b/plugins/Algolia/v1/defaultContent/manifest.json index f1604d74..c6cec2d6 100644 --- a/plugins/Algolia/v1/defaultContent/manifest.json +++ b/plugins/Algolia/v1/defaultContent/manifest.json @@ -1,6 +1,6 @@ { "items": [ { "name": "overview", "type": "dashboard" }, - { "name": "algoliaIndex", "type": "dashboard" } + { "name": "index", "type": "dashboard" } ] } diff --git a/plugins/Algolia/v1/docs/README.md b/plugins/Algolia/v1/docs/README.md index 43aae67c..736b3e4f 100644 --- a/plugins/Algolia/v1/docs/README.md +++ b/plugins/Algolia/v1/docs/README.md @@ -34,9 +34,9 @@ You need two values from the Algolia dashboard: your **Application ID** and an * ## What gets indexed -| Object type | Represents | Key properties | -| ----------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Algolia Index** | A single search index in your application | Records (entries), data size, file size, last build time (s), number of pending tasks, pending-task flag, last updated, primary index (for replicas) | +| Object type | Represents | Key properties | +| ----------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Index** | A single search index in your application | Records (entries), data size, file size, last build time (s), number of pending tasks, pending-task flag, last updated, primary index (for replicas) | Each index's object ID is its index name, which is unique within an application. From d77d1d20e8e313f248a1f783fe13a5c76bcfb46f Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Fri, 19 Jun 2026 15:42:25 +0100 Subject: [PATCH 13/19] fix Claude review comments --- plugins/Algolia/v1/dataStreams/indexes.json | 12 ++++++++++-- plugins/Algolia/v1/defaultContent/index.dash.json | 2 +- plugins/Algolia/v1/docs/README.md | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/plugins/Algolia/v1/dataStreams/indexes.json b/plugins/Algolia/v1/dataStreams/indexes.json index 04c52579..2a05028a 100644 --- a/plugins/Algolia/v1/dataStreams/indexes.json +++ b/plugins/Algolia/v1/dataStreams/indexes.json @@ -39,9 +39,17 @@ "displayName": "Pending Tasks", "shape": ["number", { "decimalPlaces": 0 }] }, - { "name": "pendingTask", "displayName": "Has Pending Task" }, + { + "name": "pendingTask", + "displayName": "Has Pending Task", + "shape": "boolean" + }, { "name": "updatedAt", "displayName": "Last Updated", "shape": "date" }, - { "name": "primary", "displayName": "Primary Index" } + { + "name": "primary", + "displayName": "Primary Index", + "shape": "boolean" + } ], "timeframes": false } diff --git a/plugins/Algolia/v1/defaultContent/index.dash.json b/plugins/Algolia/v1/defaultContent/index.dash.json index 6c542178..2a47adcd 100644 --- a/plugins/Algolia/v1/defaultContent/index.dash.json +++ b/plugins/Algolia/v1/defaultContent/index.dash.json @@ -11,7 +11,7 @@ { "i": "9b9fc2b9-c56d-47de-a4c4-d151e467a210", "x": 0, - "y": 6, + "y": 8, "w": 4, "h": 4, "moved": false, diff --git a/plugins/Algolia/v1/docs/README.md b/plugins/Algolia/v1/docs/README.md index 736b3e4f..990a4268 100644 --- a/plugins/Algolia/v1/docs/README.md +++ b/plugins/Algolia/v1/docs/README.md @@ -5,7 +5,7 @@ Monitor your [Algolia](https://www.algolia.com/) search application from Squared - **Indices** — every index in your Algolia application is imported as an object, with its record count, data/file size, last build time and pending-task count. - **Search analytics** (per index) — search volume over time, the no-results rate, your most popular searches, and the searches that returned no results. -Out of the box you get an **Overview** dashboard (totals and top indices across the whole application) and an **Algolia Index** perspective (per-index size, search volume, and search-quality tiles). +Out of the box you get an **Overview** dashboard (totals and top indices across the whole application) and an **Index** perspective (per-index size, search volume, and search-quality tiles). ## Prerequisites — getting your credentials From a547e1e56f72701ef826adb499785e547eaee517 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Mon, 22 Jun 2026 08:02:34 +0100 Subject: [PATCH 14/19] Add additional Algolia dataStreams Top countries, users, conversion rate and click-through rate --- .../v1/dataStreams/clickThroughRate.json | 56 +++++++++++++++++++ .../v1/dataStreams/conversionRate.json | 56 +++++++++++++++++++ .../Algolia/v1/dataStreams/noResultRate.json | 9 ++- .../v1/dataStreams/noResultSearches.json | 7 ++- .../v1/dataStreams/scripts/topCountries.js | 8 +++ .../Algolia/v1/dataStreams/searchCount.json | 7 ++- .../Algolia/v1/dataStreams/topCountries.json | 38 +++++++++++++ .../Algolia/v1/dataStreams/topSearches.json | 10 +++- plugins/Algolia/v1/dataStreams/topUsers.json | 43 ++++++++++++++ 9 files changed, 225 insertions(+), 9 deletions(-) create mode 100644 plugins/Algolia/v1/dataStreams/clickThroughRate.json create mode 100644 plugins/Algolia/v1/dataStreams/conversionRate.json create mode 100644 plugins/Algolia/v1/dataStreams/scripts/topCountries.js create mode 100644 plugins/Algolia/v1/dataStreams/topCountries.json create mode 100644 plugins/Algolia/v1/dataStreams/topUsers.json diff --git a/plugins/Algolia/v1/dataStreams/clickThroughRate.json b/plugins/Algolia/v1/dataStreams/clickThroughRate.json new file mode 100644 index 00000000..917fcf01 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/clickThroughRate.json @@ -0,0 +1,56 @@ +{ + "name": "clickThroughRate", + "displayName": "Click-through Rate", + "description": "Retrieves the click-through rate (CTR) for all your searches with at least one click event", + "tags": ["Analytics"], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "/2/clicks/clickThroughRate", + "getArgs": [ + { "key": "index", "value": "{{object.rawId}}" }, + { + "key": "startDate", + "value": "{{timeframeUtc.start.split('T')[0]}}" + }, + { + "key": "endDate", + "value": "{{timeframeUtc.end.split('T')[0]}}" + } + ], + "postRequestScript": "datesAddIndex.js", + "paging": { "mode": "none" } + }, + "matches": { "sourceType": { "type": "equals", "value": "Index" } }, + "metadata": [ + { + "name": "index", + "displayName": "Index", + "shape": "string", + "role": "id" + }, + { + "name": "date", + "displayName": "Date", + "shape": "date", + "role": "timestamp" + }, + { + "name": "rate", + "displayName": "Click-through Rate", + "shape": ["percent", { "asZeroToOne": true, "decimalPlaces": 0 }], + "role": "value" + }, + { + "name": "clickCount", + "displayName": "Click Count", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "trackedSearchCount", + "displayName": "Tracked Search Count", + "shape": ["number", { "decimalPlaces": 0 }] + } + ], + "timeframes": true +} diff --git a/plugins/Algolia/v1/dataStreams/conversionRate.json b/plugins/Algolia/v1/dataStreams/conversionRate.json new file mode 100644 index 00000000..f9eab488 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/conversionRate.json @@ -0,0 +1,56 @@ +{ + "name": "conversionRate", + "displayName": "Conversion Rate", + "description": "Retrieves the conversion rate (CR) for all your searches with at least one conversion event", + "tags": ["Analytics"], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "/2/conversions/conversionRate", + "getArgs": [ + { "key": "index", "value": "{{object.rawId}}" }, + { + "key": "startDate", + "value": "{{timeframeUtc.start.split('T')[0]}}" + }, + { + "key": "endDate", + "value": "{{timeframeUtc.end.split('T')[0]}}" + } + ], + "postRequestScript": "datesAddIndex.js", + "paging": { "mode": "none" } + }, + "matches": { "sourceType": { "type": "equals", "value": "Index" } }, + "metadata": [ + { + "name": "index", + "displayName": "Index", + "shape": "string", + "role": "id" + }, + { + "name": "date", + "displayName": "Date", + "shape": "date", + "role": "timestamp" + }, + { + "name": "rate", + "displayName": "Conversion Rate", + "shape": ["percent", { "asZeroToOne": true, "decimalPlaces": 0 }], + "role": "value" + }, + { + "name": "conversionCount", + "displayName": "Conversion Count", + "shape": ["number", { "decimalPlaces": 0 }] + }, + { + "name": "trackedSearchCount", + "displayName": "Tracked Search Count", + "shape": ["number", { "decimalPlaces": 0 }] + } + ], + "timeframes": true +} diff --git a/plugins/Algolia/v1/dataStreams/noResultRate.json b/plugins/Algolia/v1/dataStreams/noResultRate.json index 020c6434..2cd22ccf 100644 --- a/plugins/Algolia/v1/dataStreams/noResultRate.json +++ b/plugins/Algolia/v1/dataStreams/noResultRate.json @@ -9,8 +9,11 @@ "endpointPath": "/2/searches/noResultRate", "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, - { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, - { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" } + { + "key": "startDate", + "value": "{{timeframeUtc.start.split('T')[0]}}" + }, + { "key": "endDate", "value": "{{timeframeUtc.end.split('T')[0]}}" } ], "postRequestScript": "datesAddIndex.js" }, @@ -25,7 +28,7 @@ { "name": "rate", "displayName": "No-result rate", - "shape": ["percent", { "asZeroToOne": true }], + "shape": ["percent", { "asZeroToOne": true, "decimalPlaces": 0 }], "role": "value" }, { diff --git a/plugins/Algolia/v1/dataStreams/noResultSearches.json b/plugins/Algolia/v1/dataStreams/noResultSearches.json index 2d364bf7..a9dbd91b 100644 --- a/plugins/Algolia/v1/dataStreams/noResultSearches.json +++ b/plugins/Algolia/v1/dataStreams/noResultSearches.json @@ -9,8 +9,11 @@ "endpointPath": "/2/searches/noResults", "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, - { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, - { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" }, + { + "key": "startDate", + "value": "{{timeframeUtc.start.split('T')[0]}}" + }, + { "key": "endDate", "value": "{{timeframeUtc.end.split('T')[0]}}" }, { "key": "limit", "value": "50" } ], "postRequestScript": "searchAddIndex.js", diff --git a/plugins/Algolia/v1/dataStreams/scripts/topCountries.js b/plugins/Algolia/v1/dataStreams/scripts/topCountries.js new file mode 100644 index 00000000..fd494817 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/scripts/topCountries.js @@ -0,0 +1,8 @@ +// Add the index name to allow grouping +var object = context.objects[0]; +result = + data?.countries?.map((r) => ({ + ...r, + index: object.rawId, + })) ?? []; + diff --git a/plugins/Algolia/v1/dataStreams/searchCount.json b/plugins/Algolia/v1/dataStreams/searchCount.json index 73214535..1fed8081 100644 --- a/plugins/Algolia/v1/dataStreams/searchCount.json +++ b/plugins/Algolia/v1/dataStreams/searchCount.json @@ -9,8 +9,11 @@ "endpointPath": "/2/searches/count", "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, - { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, - { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" } + { + "key": "startDate", + "value": "{{timeframeUtc.start.split('T')[0]}}" + }, + { "key": "endDate", "value": "{{timeframeUtc.end.split('T')[0]}}" } ], "postRequestScript": "datesAddIndex.js" }, diff --git a/plugins/Algolia/v1/dataStreams/topCountries.json b/plugins/Algolia/v1/dataStreams/topCountries.json new file mode 100644 index 00000000..3e570763 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/topCountries.json @@ -0,0 +1,38 @@ +{ + "name": "topCountries", + "displayName": "Top Countries", + "description": "Retrieves the countries with the most searches in your index", + "tags": ["Analytics"], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "/2/countries", + "getArgs": [ + { "key": "index", "value": "{{object.rawId}}" }, + { + "key": "startDate", + "value": "{{timeframeUtc.start.split('T')[0]}}" + }, + { "key": "endDate", "value": "{{timeframeUtc.end.split('T')[0]}}" }, + { "key": "limit", "value": "50" } + ], + "postRequestScript": "topCountries.js", + "paging": { "mode": "none" } + }, + "matches": { "sourceType": { "type": "equals", "value": "Index" } }, + "metadata": [ + { + "name": "country", + "displayName": "Country", + "shape": "string", + "role": "label" + }, + { + "name": "count", + "displayName": "Count", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "value" + } + ], + "timeframes": true +} diff --git a/plugins/Algolia/v1/dataStreams/topSearches.json b/plugins/Algolia/v1/dataStreams/topSearches.json index c9d5c9b8..a20f27b6 100644 --- a/plugins/Algolia/v1/dataStreams/topSearches.json +++ b/plugins/Algolia/v1/dataStreams/topSearches.json @@ -9,8 +9,14 @@ "endpointPath": "/2/searches", "getArgs": [ { "key": "index", "value": "{{object.rawId}}" }, - { "key": "startDate", "value": "{{timeframe.start.slice(0,10)}}" }, - { "key": "endDate", "value": "{{timeframe.end.slice(0,10)}}" }, + { + "key": "startDate", + "value": "{{timeframeUtc.start.split('T')[0]}}" + }, + { + "key": "endDate", + "value": "{{timeframeUtc.end.split('T')[0]}}" + }, { "key": "limit", "value": "50" } ], "postRequestScript": "searchAddIndex.js", diff --git a/plugins/Algolia/v1/dataStreams/topUsers.json b/plugins/Algolia/v1/dataStreams/topUsers.json new file mode 100644 index 00000000..4dfd73f6 --- /dev/null +++ b/plugins/Algolia/v1/dataStreams/topUsers.json @@ -0,0 +1,43 @@ +{ + "name": "numberOfUsers", + "displayName": "Number of users", + "description": "Retrieves the number of unique users for an index over the selected timeframe", + "tags": ["Analytics"], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "/2/users/count", + "getArgs": [ + { "key": "index", "value": "{{object.rawId}}" }, + { + "key": "startDate", + "value": "{{timeframeUtc.start.split('T')[0]}}" + }, + { "key": "endDate", "value": "{{timeframeUtc.end.split('T')[0]}}" } + ], + "postRequestScript": "datesAddIndex.js", + "paging": { "mode": "none" } + }, + "matches": { "sourceType": { "type": "equals", "value": "Index" } }, + "metadata": [ + { + "name": "index", + "displayName": "Index", + "shape": "string", + "role": "id" + }, + { + "name": "date", + "displayName": "Date", + "shape": "date", + "role": "timestamp" + }, + { + "name": "count", + "displayName": "Count", + "shape": ["number", { "decimalPlaces": 0 }], + "role": "value" + } + ], + "timeframes": true +} From d6226ed7245b268074cba913e7e9b99d0d6b0636 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Mon, 22 Jun 2026 08:27:31 +0100 Subject: [PATCH 15/19] update index dashboard to show kpis --- .../Algolia/v1/defaultContent/index.dash.json | 445 +++++++++++++----- 1 file changed, 339 insertions(+), 106 deletions(-) diff --git a/plugins/Algolia/v1/defaultContent/index.dash.json b/plugins/Algolia/v1/defaultContent/index.dash.json index 2a47adcd..73b39c14 100644 --- a/plugins/Algolia/v1/defaultContent/index.dash.json +++ b/plugins/Algolia/v1/defaultContent/index.dash.json @@ -1,228 +1,461 @@ { "name": "Index", "schemaVersion": "1.5", - "timeframe": "last30days", + "timeframe": "last7days", "variables": ["{{variables.[Algolia Index]}}"], "dashboard": { "_type": "layout/grid", - "columns": 4, "version": 1, "contents": [ { - "i": "9b9fc2b9-c56d-47de-a4c4-d151e467a210", + "w": 1, + "h": 2, "x": 0, - "y": 8, - "w": 4, - "h": 4, + "y": 0, + "z": 0, + "i": "d5bc5bb9-7ef6-400d-9891-453a961e3df7", "moved": false, "static": false, - "z": 0, "config": { + "variables": ["{{variables.[Algolia Index]}}"], + "dataStream": { + "name": "searchCount", + "id": "{{dataStreams.[searchCount]}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": ["count"] + } + ] + } + }, + "scope": { + "variable": "{{variables.[Algolia Index]}}", + "workspace": "{{workspaceId}}", + "scope": "{{scopes.[Algolia Indices]}}" + }, "_type": "tile/data-stream", - "title": "Index Details", "description": "", - "timeframe": "none", "activePluginConfigIds": ["{{configId}}"], + "title": "", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "comparisonColumn": "none", + "label": "Total searches", + "value": "count_sum", + "labelPosition": "bottom" + } + } + } + } + }, + { + "w": 1, + "h": 2, + "x": 1, + "y": 0, + "z": 0, + "i": "cc9cf8e5-39ca-45eb-beb3-bc1b18985ea4", + "moved": false, + "static": false, + "config": { + "variables": ["{{variables.[Algolia Index]}}"], "dataStream": { - "id": "datastream-properties", - "pluginConfigId": "{{configId}}" + "name": "conversionRate", + "id": "{{dataStreams.[conversionRate]}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "mean", + "names": ["rate"] + } + ] + }, + "metadata": [ + { + "shape": [ + "percent", + { + "thousandsSeparator": true, + "decimalPlaces": 0, + "asZeroToOne": true + } + ], + "name": "rate_mean" + } + ] }, "scope": { - "scope": "{{scopes.[Algolia Indices]}}", + "variable": "{{variables.[Algolia Index]}}", "workspace": "{{workspaceId}}", - "variable": "{{variables.[Algolia Index]}}" + "scope": "{{scopes.[Algolia Indices]}}" }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "title": "", + "visualisation": { + "config": { + "data-stream-scalar": { + "value": "rate_mean", + "comparisonColumn": "none", + "label": "Conversion Rate" + } + }, + "type": "data-stream-scalar" + } + } + }, + { + "w": 1, + "h": 2, + "x": 2, + "y": 0, + "z": 0, + "i": "39fcefbc-ad87-4c4a-bf57-0567e906d83a", + "moved": false, + "static": false, + "config": { "variables": ["{{variables.[Algolia Index]}}"], + "dataStream": { + "name": "noResultRate", + "metadata": [ + { + "shape": [ + "percent", + { + "thousandsSeparator": true, + "decimalPlaces": 0, + "asZeroToOne": true + } + ], + "name": "rate_mean" + } + ], + "id": "{{dataStreams.[noResultRate]}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "mean", + "names": ["rate"] + } + ] + } + }, + "scope": { + "variable": "{{variables.[Algolia Index]}}", + "workspace": "{{workspaceId}}", + "scope": "{{scopes.[Algolia Indices]}}" + }, + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "title": "", "visualisation": { - "type": "data-stream-table", + "type": "data-stream-scalar", "config": { - "data-stream-table": { - "transpose": true + "data-stream-scalar": { + "value": "rate_mean", + "comparisonColumn": "none", + "label": "No-result rate" } } } } }, { - "i": "dfa41039-1657-4142-b6a5-16ac7abffb9d", - "x": 0, - "y": 4, - "w": 2, - "h": 4, + "w": 1, + "h": 2, + "x": 3, + "y": 0, + "z": 0, + "i": "aad2ae3b-bfad-45a9-b416-c1ce40588b52", "moved": false, "static": false, - "z": 0, "config": { + "variables": ["{{variables.[Algolia Index]}}"], + "dataStream": { + "name": "clickThroughRate", + "metadata": [ + { + "shape": [ + "percent", + { + "thousandsSeparator": true, + "decimalPlaces": 0, + "asZeroToOne": true + } + ], + "name": "rate_mean" + } + ], + "id": "{{dataStreams.[clickThroughRate]}}", + "group": { + "by": [], + "aggregate": [ + { + "type": "mean", + "names": ["rate"] + } + ] + } + }, + "scope": { + "variable": "{{variables.[Algolia Index]}}", + "workspace": "{{workspaceId}}", + "scope": "{{scopes.[Algolia Indices]}}" + }, "_type": "tile/data-stream", - "title": "Search Volume", "description": "", "activePluginConfigIds": ["{{configId}}"], + "title": "", + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "rate_mean", + "comparisonColumn": "none", + "label": "Click-through rate" + } + } + } + } + }, + { + "w": 2, + "h": 4, + "x": 0, + "y": 2, + "z": 0, + "i": "1c816936-aafc-42dc-8096-10f0281a6e17", + "moved": false, + "static": false, + "config": { + "variables": ["{{variables.[Algolia Index]}}"], "dataStream": { - "id": "{{dataStreams.[searchCount]}}", - "name": "searchCount", + "name": "topSearches", "pluginConfigId": "{{configId}}", - "group": { - "by": [["date", "byDay"]], - "aggregate": [{ "type": "sum", "names": ["count"] }] - }, + "id": "{{dataStreams.[topSearches]}}", "sort": { - "by": [["date_byDay", "asc"]] + "by": [["count", "desc"]] } }, "scope": { - "scope": "{{scopes.[Algolia Indices]}}", + "variable": "{{variables.[Algolia Index]}}", "workspace": "{{workspaceId}}", - "variable": "{{variables.[Algolia Index]}}" + "scope": "{{scopes.[Algolia Indices]}}" }, - "variables": ["{{variables.[Algolia Index]}}"], + "_type": "tile/data-stream", + "description": "The most popular search queries with how many results they return", + "activePluginConfigIds": ["{{configId}}"], + "baseTile": "data-stream-base-tile", + "title": "Top Searches", "visualisation": { - "type": "data-stream-line-graph", + "type": "data-stream-table", "config": { - "data-stream-line-graph": { - "xAxisColumn": "date_byDay", - "yAxisColumn": ["count_sum"], - "seriesColumn": "none", - "showLegend": false, - "legendPosition": "bottom", - "yAxisLabel": "Searches", - "showYAxisLabel": true, - "showTrendLine": false + "data-stream-table": { + "columnOrder": ["search", "count", "nbHits"], + "resizedColumns": { + "columnWidths": { + "search": 448 + } + }, + "transpose": false } } } } }, { - "i": "09cc7897-4e96-44b3-9205-144fcf3ef5fb", - "x": 2, - "y": 4, "w": 2, "h": 4, + "x": 2, + "y": 2, + "z": 0, + "i": "1727a100-9c88-41cb-b157-c0f197b1b13e", "moved": false, "static": false, - "z": 0, "config": { + "variables": ["{{variables.[Algolia Index]}}"], + "dataStream": { + "name": "noResultSearches", + "pluginConfigId": "{{configId}}", + "id": "{{dataStreams.[noResultSearches]}}", + "sort": { + "by": [["count", "desc"]] + } + }, + "scope": { + "variable": "{{variables.[Algolia Index]}}", + "workspace": "{{workspaceId}}", + "scope": "{{scopes.[Algolia Indices]}}" + }, "_type": "tile/data-stream", - "title": "No-Result Rate", - "description": "", + "description": "The following queries are not returning any results", "activePluginConfigIds": ["{{configId}}"], + "title": "Searches With No Results", + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": ["search", "count", "index"], + "hiddenColumns": ["withFilterCount"], + "transpose": false + } + } + } + } + }, + { + "w": 2, + "h": 3, + "x": 0, + "y": 6, + "z": 0, + "i": "dfa41039-1657-4142-b6a5-16ac7abffb9d", + "moved": false, + "static": false, + "config": { + "variables": ["{{variables.[Algolia Index]}}"], "dataStream": { - "id": "{{dataStreams.[noResultRate]}}", - "name": "noResultRate", + "name": "searchCount", "pluginConfigId": "{{configId}}", - "group": { - "by": [["date", "byDay"]], - "aggregate": [{ "type": "mean", "names": ["rate"] }] - }, + "id": "{{dataStreams.[searchCount]}}", "sort": { "by": [["date_byDay", "asc"]] + }, + "group": { + "by": [["date", "byDay"]], + "aggregate": [ + { + "type": "sum", + "names": ["count"] + } + ] } }, "scope": { - "scope": "{{scopes.[Algolia Indices]}}", + "variable": "{{variables.[Algolia Index]}}", "workspace": "{{workspaceId}}", - "variable": "{{variables.[Algolia Index]}}" + "scope": "{{scopes.[Algolia Indices]}}" }, - "variables": ["{{variables.[Algolia Index]}}"], + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "title": "Search Volume", "visualisation": { "type": "data-stream-line-graph", "config": { "data-stream-line-graph": { + "yAxisLabel": "Searches", "xAxisColumn": "date_byDay", - "yAxisColumn": ["rate_mean"], - "seriesColumn": "none", "showLegend": false, - "legendPosition": "bottom", - "yAxisLabel": "No-Result Rate", "showYAxisLabel": true, - "showTrendLine": false + "seriesColumn": "none", + "showTrendLine": false, + "legendPosition": "bottom", + "yAxisColumn": ["count_sum"] } } } } }, { - "i": "1c816936-aafc-42dc-8096-10f0281a6e17", - "x": 0, - "y": 0, "w": 2, - "h": 4, + "h": 3, + "x": 2, + "y": 6, + "z": 0, + "i": "09cc7897-4e96-44b3-9205-144fcf3ef5fb", "moved": false, "static": false, - "z": 0, "config": { - "_type": "tile/data-stream", - "title": "Top Searches", - "description": "", - "activePluginConfigIds": ["{{configId}}"], + "variables": ["{{variables.[Algolia Index]}}"], "dataStream": { - "id": "{{dataStreams.[topSearches]}}", - "name": "topSearches", + "name": "noResultRate", "pluginConfigId": "{{configId}}", + "id": "{{dataStreams.[noResultRate]}}", "sort": { - "by": [["count", "desc"]] + "by": [["date_byDay", "asc"]] + }, + "group": { + "by": [["date", "byDay"]], + "aggregate": [ + { + "type": "mean", + "names": ["rate"] + } + ] } }, "scope": { - "scope": "{{scopes.[Algolia Indices]}}", + "variable": "{{variables.[Algolia Index]}}", "workspace": "{{workspaceId}}", - "variable": "{{variables.[Algolia Index]}}" + "scope": "{{scopes.[Algolia Indices]}}" }, - "variables": ["{{variables.[Algolia Index]}}"], + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "title": "No-Result Rate", "visualisation": { - "type": "data-stream-table", + "type": "data-stream-line-graph", "config": { - "data-stream-table": { - "transpose": false, - "columnOrder": ["search", "count", "nbHits"] + "data-stream-line-graph": { + "yAxisLabel": "No-Result Rate", + "xAxisColumn": "date_byDay", + "showLegend": false, + "showYAxisLabel": true, + "seriesColumn": "none", + "showTrendLine": false, + "legendPosition": "bottom", + "yAxisColumn": ["rate_mean"] } } } } }, { - "i": "1727a100-9c88-41cb-b157-c0f197b1b13e", - "x": 2, - "y": 0, - "w": 2, + "w": 4, "h": 4, + "x": 0, + "y": 11, + "z": 0, + "i": "9b9fc2b9-c56d-47de-a4c4-d151e467a210", "moved": false, "static": false, - "z": 0, "config": { - "_type": "tile/data-stream", - "title": "Searches With No Results", - "description": "", - "activePluginConfigIds": ["{{configId}}"], + "timeframe": "none", + "variables": ["{{variables.[Algolia Index]}}"], "dataStream": { - "id": "{{dataStreams.[noResultSearches]}}", - "name": "noResultSearches", "pluginConfigId": "{{configId}}", - "sort": { - "by": [["count", "desc"]] - } + "id": "datastream-properties" }, "scope": { - "scope": "{{scopes.[Algolia Indices]}}", + "variable": "{{variables.[Algolia Index]}}", "workspace": "{{workspaceId}}", - "variable": "{{variables.[Algolia Index]}}" + "scope": "{{scopes.[Algolia Indices]}}" }, - "variables": ["{{variables.[Algolia Index]}}"], + "_type": "tile/data-stream", + "description": "", + "activePluginConfigIds": ["{{configId}}"], + "title": "Index Details", "visualisation": { "type": "data-stream-table", "config": { "data-stream-table": { - "transpose": false, - "columnOrder": [ - "search", - "count", - "withFilterCount" - ] + "transpose": true } } } } } - ] + ], + "columns": 4 } } From fc610dc826dcfac143bbb4485f51de8235f56ca1 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Mon, 22 Jun 2026 10:08:44 +0100 Subject: [PATCH 16/19] Ensure dataStreams add index metadata --- plugins/Algolia/v1/dataStreams/noResultRate.json | 6 ++++++ plugins/Algolia/v1/dataStreams/topCountries.json | 6 ++++++ plugins/Algolia/v1/dataStreams/topSearches.json | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/plugins/Algolia/v1/dataStreams/noResultRate.json b/plugins/Algolia/v1/dataStreams/noResultRate.json index 2cd22ccf..2d444f32 100644 --- a/plugins/Algolia/v1/dataStreams/noResultRate.json +++ b/plugins/Algolia/v1/dataStreams/noResultRate.json @@ -19,6 +19,12 @@ }, "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ + { + "name": "index", + "displayName": "Index", + "shape": "string", + "role": "id" + }, { "name": "date", "displayName": "Date", diff --git a/plugins/Algolia/v1/dataStreams/topCountries.json b/plugins/Algolia/v1/dataStreams/topCountries.json index 3e570763..195e09f8 100644 --- a/plugins/Algolia/v1/dataStreams/topCountries.json +++ b/plugins/Algolia/v1/dataStreams/topCountries.json @@ -21,6 +21,12 @@ }, "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ + { + "name": "index", + "displayName": "Index", + "shape": "string", + "role": "id" + }, { "name": "country", "displayName": "Country", diff --git a/plugins/Algolia/v1/dataStreams/topSearches.json b/plugins/Algolia/v1/dataStreams/topSearches.json index a20f27b6..2666fa13 100644 --- a/plugins/Algolia/v1/dataStreams/topSearches.json +++ b/plugins/Algolia/v1/dataStreams/topSearches.json @@ -24,6 +24,12 @@ }, "matches": { "sourceType": { "type": "equals", "value": "Index" } }, "metadata": [ + { + "name": "index", + "displayName": "Index", + "shape": "string", + "role": "id" + }, { "name": "search", "displayName": "Search", From d5395f89de6b8e98294cbb6ea01305b9453cb1d0 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Mon, 22 Jun 2026 10:40:33 +0100 Subject: [PATCH 17/19] hide index column from table --- plugins/Algolia/v1/defaultContent/index.dash.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/Algolia/v1/defaultContent/index.dash.json b/plugins/Algolia/v1/defaultContent/index.dash.json index 73b39c14..bdc00fc5 100644 --- a/plugins/Algolia/v1/defaultContent/index.dash.json +++ b/plugins/Algolia/v1/defaultContent/index.dash.json @@ -261,6 +261,7 @@ "config": { "data-stream-table": { "columnOrder": ["search", "count", "nbHits"], + "hiddenColumns": ["index"], "resizedColumns": { "columnWidths": { "search": 448 @@ -304,8 +305,8 @@ "type": "data-stream-table", "config": { "data-stream-table": { - "columnOrder": ["search", "count", "index"], - "hiddenColumns": ["withFilterCount"], + "columnOrder": ["search", "count"], + "hiddenColumns": ["withFilterCount", "index"], "transpose": false } } @@ -424,7 +425,7 @@ "w": 4, "h": 4, "x": 0, - "y": 11, + "y": 9, "z": 0, "i": "9b9fc2b9-c56d-47de-a4c4-d151e467a210", "moved": false, From 0aac8557249a68cba8cda9252da3c451275eeae0 Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Mon, 22 Jun 2026 16:12:17 +0100 Subject: [PATCH 18/19] Review tweaks for Algolia plugin --- plugins/Algolia/v1/defaultContent/index.dash.json | 2 +- .../Algolia/v1/defaultContent/overview.dash.json | 15 +++++++-------- plugins/Algolia/v1/docs/README.md | 4 ++-- plugins/Algolia/v1/ui.json | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/plugins/Algolia/v1/defaultContent/index.dash.json b/plugins/Algolia/v1/defaultContent/index.dash.json index bdc00fc5..0ec84ee9 100644 --- a/plugins/Algolia/v1/defaultContent/index.dash.json +++ b/plugins/Algolia/v1/defaultContent/index.dash.json @@ -306,7 +306,7 @@ "config": { "data-stream-table": { "columnOrder": ["search", "count"], - "hiddenColumns": ["withFilterCount", "index"], + "hiddenColumns": ["index"], "transpose": false } } diff --git a/plugins/Algolia/v1/defaultContent/overview.dash.json b/plugins/Algolia/v1/defaultContent/overview.dash.json index b243e04b..08f2bfcb 100644 --- a/plugins/Algolia/v1/defaultContent/overview.dash.json +++ b/plugins/Algolia/v1/defaultContent/overview.dash.json @@ -101,13 +101,11 @@ "name": "searchCount", "group": { "by": [["index", "uniqueValues"]], - "aggregate": [ - { "type": "sum", "names": ["count"] } - ] + "aggregate": [{ "type": "sum", "names": ["count"] }] } }, "scope": { - "query": "g.V().order().by('__name').hasNot('__canonicalType').has(\"__configId\", within(\"{{configId}}\")).or(__.has(\"sourceType\", \"Index\")).limit(500)", + "query": "g.V().order().by('__name').hasNot('__canonicalType').has(\"__configId\", within(\"{{configId}}\")).has(\"sourceType\", \"Index\").limit(500)", "bindings": {}, "queryDetail": {} }, @@ -210,9 +208,7 @@ }, "group": { "by": [["search", "uniqueValues"]], - "aggregate": [ - { "type": "sum", "names": ["count"] } - ] + "aggregate": [{ "type": "sum", "names": ["count"] }] }, "sort": { "top": 10, @@ -228,7 +224,10 @@ "type": "data-stream-table", "config": { "data-stream-table": { - "columnOrder": ["search_uniqueValues", "count_sum"], + "columnOrder": [ + "search_uniqueValues", + "count_sum" + ], "hiddenColumns": [] } } diff --git a/plugins/Algolia/v1/docs/README.md b/plugins/Algolia/v1/docs/README.md index 990a4268..0f465ff4 100644 --- a/plugins/Algolia/v1/docs/README.md +++ b/plugins/Algolia/v1/docs/README.md @@ -20,7 +20,7 @@ You need two values from the Algolia dashboard: your **Application ID** and an * - `analytics` — to read Search Analytics - Leave **Indices** set to _all_ (or restrict to the indices you want to monitor). - A read-only **Search-Only API Key** is **not** sufficient — it lacks `listIndexes` and `analytics`. + A read-only **Search-Only API Key** is **not** sufficient — it lacks `listIndexes` ,`settings` and `analytics`. > **Tip:** Using a scoped custom key rather than your Admin key follows least-privilege best practice and means the key can be rotated without affecting other integrations. @@ -29,7 +29,7 @@ You need two values from the Algolia dashboard: your **Application ID** and an * | Field | Required | What it is / where to find it | | -------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Application ID** | Yes | Your Algolia Application ID, from **Settings → API Keys** in the Algolia dashboard. Also forms your API host (`https://.algolia.net`). | -| **API Key** | Yes | An Admin key, or a custom key with the `listIndexes`, `settings` and `analytics` ACLs (see above). Stored encrypted. | +| **API key** | Yes | An Admin key, or a custom key with the `listIndexes`, `settings` and `analytics` ACLs (see above). Stored encrypted. | | **Analytics region** | No (default **US**) | The region your Algolia app's analytics data is stored in. Choose **EU** only if your application was created in Algolia's EU (Germany) region — otherwise analytics tiles will be empty. Defaults to US. | ## What gets indexed diff --git a/plugins/Algolia/v1/ui.json b/plugins/Algolia/v1/ui.json index 175a2a5b..e5800c2f 100644 --- a/plugins/Algolia/v1/ui.json +++ b/plugins/Algolia/v1/ui.json @@ -10,7 +10,7 @@ { "type": "password", "name": "apiKey", - "label": "API Key", + "label": "API key", "help": "An Algolia **Admin API Key**, or a custom key with the `listIndexes`, `settings` and `analytics` ACLs. A Search-Only key will not work. Found under **Settings → API Keys**.", "validation": { "required": true } }, From cb04e2085ae2eea47cdd2b1d897096582aef467e Mon Sep 17 00:00:00 2001 From: Andrew Harris Date: Mon, 22 Jun 2026 16:24:54 +0100 Subject: [PATCH 19/19] fix inconsistent spacing --- plugins/Algolia/v1/docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Algolia/v1/docs/README.md b/plugins/Algolia/v1/docs/README.md index 0f465ff4..1d2dc488 100644 --- a/plugins/Algolia/v1/docs/README.md +++ b/plugins/Algolia/v1/docs/README.md @@ -20,7 +20,7 @@ You need two values from the Algolia dashboard: your **Application ID** and an * - `analytics` — to read Search Analytics - Leave **Indices** set to _all_ (or restrict to the indices you want to monitor). - A read-only **Search-Only API Key** is **not** sufficient — it lacks `listIndexes` ,`settings` and `analytics`. + A read-only **Search-Only API Key** is **not** sufficient — it lacks `listIndexes`, `settings` and `analytics`. > **Tip:** Using a scoped custom key rather than your Admin key follows least-privilege best practice and means the key can be rotated without affecting other integrations.