From fb3b4c8f7d2d8af49bbf0735a75df0796b9ff423 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 11 Jan 2025 13:38:06 +0100 Subject: [PATCH] updated elastic autocomplete to include persons, also adds debounce & clearer handling of response --- src/api.ts | 69 ++++++++++---- .../header/AutocompleteDropdown.vue | 93 ++++++++++++------- src/components/header/SearchInput.vue | 25 ++++- src/interfaces/IAutocompleteSearch.ts | 24 +++++ 4 files changed, 155 insertions(+), 56 deletions(-) diff --git a/src/api.ts b/src/api.ts index 0d67b87..898b19e 100644 --- a/src/api.ts +++ b/src/api.ts @@ -4,7 +4,7 @@ import type { IRequestSubmitResponse } from "./interfaces/IRequestResponse"; -const { ELASTIC, ELASTIC_INDEX } = process.env; +const { ELASTIC, ELASTIC_INDEX, ELASTIC_APIKEY } = process.env; const API_HOSTNAME = window.location.origin; // - - - TMDB - - - @@ -430,9 +430,13 @@ const unlinkPlexAccount = () => { // - - - User graphs - - - -const fetchGraphData = (urlPath, days, chartType) => { +const fetchGraphData = async ( + urlPath: string, + days: number, + chartType: string +) => { const url = new URL(`/api/v1/user/${urlPath}`, API_HOSTNAME); - url.searchParams.append("days", days); + url.searchParams.append("days", String(days)); url.searchParams.append("y_axis", chartType); return fetch(url.href).then(resp => { @@ -447,7 +451,7 @@ const fetchGraphData = (urlPath, days, chartType) => { // - - - Random emoji - - - -const getEmoji = () => { +const getEmoji = async () => { const url = new URL("/api/v1/emoji", API_HOSTNAME); return fetch(url.href) @@ -468,33 +472,58 @@ const getEmoji = () => { * @param {string} query * @returns {object} List of movies and shows matching query */ -const elasticSearchMoviesAndShows = (query, count = 22) => { +const elasticSearchMoviesAndShows = (query: string, count = 22) => { const url = new URL(`${ELASTIC_INDEX}/_search`, ELASTIC); const body = { sort: [{ popularity: { order: "desc" } }, "_score"], + size: count, query: { - bool: { - should: [ - { - match_phrase_prefix: { - original_name: query - } - }, - { - match_phrase_prefix: { - original_title: query - } - } - ] + multi_match: { + query, + fields: ["name", "original_title", "original_name"], + type: "phrase_prefix", + tie_breaker: 0.3 } }, - size: count + suggest: { + text: query, + "person-suggest": { + prefix: query, + completion: { + field: "name.completion", + fuzzy: { + fuzziness: "AUTO" + } + } + }, + "movie-suggest": { + prefix: query, + completion: { + field: "original_title.completion", + fuzzy: { + fuzziness: "AUTO" + } + } + }, + "show-suggest": { + prefix: query, + completion: { + field: "original_name.completion", + fuzzy: { + fuzziness: "AUTO" + } + } + } + } }; const options = { method: "POST", - headers: { "Content-Type": "application/json" }, + headers: { + Authorization: `ApiKey ${ELASTIC_APIKEY}`, + "Content-Type": "application/json" + }, body: JSON.stringify(body) }; diff --git a/src/components/header/AutocompleteDropdown.vue b/src/components/header/AutocompleteDropdown.vue index c9bc5fa..4383055 100644 --- a/src/components/header/AutocompleteDropdown.vue +++ b/src/components/header/AutocompleteDropdown.vue @@ -10,6 +10,7 @@ > + {{ result.title }} @@ -23,18 +24,25 @@ + +