From d135ab2d5087c81b6837fa3a1a3b98c412a08ec4 Mon Sep 17 00:00:00 2001 From: frankporras Date: Thu, 13 Jun 2024 17:01:14 +0200 Subject: [PATCH] Progress OpenSearch. Pending solving onFilter issue with active filters --- src/api/api.ts | 3 + src/components/face-category/FacetCategory.ts | 2 + .../face-category/facet-category.vue | 3 + src/components/vs-input/vs-input.ts | 24 +--- src/components/vs-result/vs-result.ts | 6 +- src/components/vs-result/vs-result.vue | 3 +- src/models/dataset.ts | 2 +- src/models/headers.ts | 2 + src/services/dataset.service.ts | 10 +- .../dataset-detail.component.ts | 2 +- .../search-view/search-view-component.ts | 134 +++++++++++------- 11 files changed, 109 insertions(+), 82 deletions(-) diff --git a/src/api/api.ts b/src/api/api.ts index 8a7db0a..639d35b 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -20,6 +20,9 @@ const get = (url: string, queryParams?: any): Observable => { // Function to make a POST request using Axios wrapped in an Observable const post = (url: string, body: any, queryParams?: any): Observable => { // Use defer to create an Observable that makes the Axios POST request when subscribed to + // console.log(body); + // console.log(queryParams); + return defer(() => axiosInstance.post(url, body, { params: queryParams, headers: { diff --git a/src/components/face-category/FacetCategory.ts b/src/components/face-category/FacetCategory.ts index 8a3f5c2..7669705 100644 --- a/src/components/face-category/FacetCategory.ts +++ b/src/components/face-category/FacetCategory.ts @@ -20,6 +20,7 @@ export default class FacetCategory extends Vue { filterName!: string; get alias(): string { + console.log("filterName:", this.filterName); return this.filterName == "datatype" ? "doctype" : this.filterName; } @@ -53,6 +54,7 @@ export default class FacetCategory extends Vue { @Emit("filter") activateItem(filterItem: FacetItem): FacetItem { + // console.log(filterItem); filterItem.category = this.alias; filterItem.active = true; // this.$emit("filter", filterItem); diff --git a/src/components/face-category/facet-category.vue b/src/components/face-category/facet-category.vue index 4dd196d..bc278c8 100644 --- a/src/components/face-category/facet-category.vue +++ b/src/components/face-category/facet-category.vue @@ -8,6 +8,9 @@
  • + {{ item.active }} + {{ item.val }} + {{ item.count }} // {{ item.val }} ({{ item.count }})
  • diff --git a/src/components/vs-input/vs-input.ts b/src/components/vs-input/vs-input.ts index c0f2706..128a95c 100644 --- a/src/components/vs-input/vs-input.ts +++ b/src/components/vs-input/vs-input.ts @@ -210,7 +210,7 @@ export default class VsInput extends Vue { // Handler for search input change searchChanged(): void { - console.log("Search changed!"); + // console.log("Search changed!"); this.selectedIndex = -1; // Let's warn the parent that a change was made // this.$emit("input", this.display); @@ -224,7 +224,7 @@ export default class VsInput extends Vue { // Perform the search request private resourceSearch() { - console.log("resourceSearch"); + // console.log("resourceSearch"); if (!this.display) { this.results = []; return; @@ -252,14 +252,11 @@ export default class VsInput extends Vue { this.highlights = highlights; // Store highlights // console.log(datasets); - // this.$emit("search", this.display); - // this.loading = false; } // Handle errors from the search request private errorHandler(err: string): void { this.error = err; - // this.loading = false; } /** @@ -321,18 +318,14 @@ export default class VsInput extends Vue { @Emit("search-change") private select(obj: Suggestion): Suggestion { - // if (!obj) { - // return; - // } - console.log("select"); - this.value = obj; //(obj["title_output"]) ? obj["title_output"] : obj.id + console.log("select:"); + this.value = obj; console.log(obj); - this.display = obj.value; // this.formatDisplay(obj) - // this.selectedDisplay = this.display; + this.display = obj.value; this.close(); - // this.$emit("update", this.value); + return this.value; } @@ -355,12 +348,7 @@ export default class VsInput extends Vue { if (!this.value) { this.clear(); } - // if (this.selectedDisplay !== this.display && this.value) { - // this.display = this.selectedDisplay; - // } this.results = []; this.error = ""; - //this.removeEventListener() - // this.$emit("close"); } } diff --git a/src/components/vs-result/vs-result.ts b/src/components/vs-result/vs-result.ts index 6984809..d731acc 100644 --- a/src/components/vs-result/vs-result.ts +++ b/src/components/vs-result/vs-result.ts @@ -23,13 +23,15 @@ export default class VsResult extends Vue { .join("."); } - private convert(unixtimestamp: number): string { + // private convert(unixtimestamp: number): string { // SOLR + private convert(unixtimestamp: string): string { // OpenSearch // Unixtimestamp // var unixtimestamp = document.getElementById('timestamp').value; // Months array const months_arr = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; // Convert timestamp to milliseconds - const date = new Date(unixtimestamp * 1000); + // const date = new Date(unixtimestamp * 1000); // SOLR + const date = new Date(Number(unixtimestamp) * 1000); // OpenSearch // Year const year = date.getFullYear(); // Month diff --git a/src/components/vs-result/vs-result.vue b/src/components/vs-result/vs-result.vue index d2f1784..20c7479 100644 --- a/src/components/vs-result/vs-result.vue +++ b/src/components/vs-result/vs-result.vue @@ -20,7 +20,8 @@ {{ convert(document.server_date_published) + ": " }} - {{ document.abstract_output }} + + {{ document.abstract[0] }} ... diff --git a/src/models/dataset.ts b/src/models/dataset.ts index f4b672b..2c141d4 100644 --- a/src/models/dataset.ts +++ b/src/models/dataset.ts @@ -82,7 +82,7 @@ export class Suggestion { export enum SearchType { Title = "title", Author = "author", - Subject = "subject" + Subject = "subjects" // ** !! The field has this name in OpenSearch!! } export class DbDataset { diff --git a/src/models/headers.ts b/src/models/headers.ts index c96835e..87e370b 100644 --- a/src/models/headers.ts +++ b/src/models/headers.ts @@ -26,6 +26,7 @@ export interface ResponseContent { docs: Array; } +//Used export class FacetResults { [key: string]: Array; } @@ -39,6 +40,7 @@ export interface FacetInstance { [key: string]: Array; } +//Used export class FacetItem { val: string; count: number; diff --git a/src/services/dataset.service.ts b/src/services/dataset.service.ts index 7fc03fb..485efb9 100644 --- a/src/services/dataset.service.ts +++ b/src/services/dataset.service.ts @@ -146,8 +146,10 @@ class DatasetService { const lowercaseTerm = typeof suggestion === 'string' ? suggestion.toLowerCase() : suggestion.value.toLowerCase(); - console.log("facetedsearchOPEN > suggestion entered:"); - console.log(suggestion); + // console.log("facetedsearchOPEN > suggestion entered:"); + // console.log(suggestion); + // console.log("typeof:", typeof suggestion); + /** * The query construction depends on whether the suggestion is a string or a Suggestion object. */ @@ -169,7 +171,7 @@ class DatasetService { // When suggestion is a suggestion object : { match: { - [suggestion.type.toLowerCase()]: { + [suggestion.type]: { query: suggestion.value, operator: 'and' // all the terms in the query must be present in the field } @@ -219,7 +221,7 @@ class DatasetService { // // })) // ); const stations = api.post(base, body); - + return stations; } diff --git a/src/views/dataset-detail.component/dataset-detail.component.ts b/src/views/dataset-detail.component/dataset-detail.component.ts index 8a3d435..9b35e58 100644 --- a/src/views/dataset-detail.component/dataset-detail.component.ts +++ b/src/views/dataset-detail.component/dataset-detail.component.ts @@ -59,7 +59,7 @@ export default class DatasetDetailComponent extends Vue { } onSearch(suggestion: Suggestion | string): void { - console.log("onSearch"); + console.log("onSearch (dataset-detail.component)"); const host = window.location.host; const parts = host.split("."); diff --git a/src/views/search-view/search-view-component.ts b/src/views/search-view/search-view-component.ts index a8bdd8c..dbc933d 100644 --- a/src/views/search-view/search-view-component.ts +++ b/src/views/search-view/search-view-component.ts @@ -68,6 +68,8 @@ export default class SearchViewComponent extends Vue { // Computed property to get search term as string get stringSearchTerm(): string { + // console.log("stringSearchTerm:", this.searchTerm); + if (typeof this.searchTerm === "string") { return this.searchTerm; } else if (this.searchTerm instanceof Suggestion) { @@ -147,13 +149,24 @@ export default class SearchViewComponent extends Vue { // Handle the search results private dataHandlerOPEN(res: OpenSearchResponse, filterItem?: FacetItem): void { - // console.log("dataHandlerOPEN (datasets, highlights):"); - // console.log(datasets); - // console.log(highlights); - this.results = res.hits.hits.map(hit => hit._source); this.numFound = res.hits.total.value; + // console.log("dataHandlerOPEN (results, numFound):"); + // console.log(this.results); + // console.log(this.numFound); + // console.log(res.hits.hits); + // console.log(res.hits.total.value); + + // for (const key in this.results) { + // if (Object.prototype.hasOwnProperty.call(this.results, key)) { + // const element = this.results[key]; + // // console.log(element.abstract[0]); + // // console.log(element.language); + // console.log(element.server_date_published); + // } + // } + this.pagination.total = res.hits.total.value; this.pagination.perPage = 10; this.pagination.data = this.results; @@ -178,9 +191,9 @@ export default class SearchViewComponent extends Vue { // Method to handle search response private dataHandler(res: SolrResponse, filterItem?: FacetItem): void { - console.log("dataHandlerSOLR (docs, numFound):"); - console.log(res.response.docs); - console.log(res.response.numFound); + // console.log("dataHandlerSOLR (docs, numFound):"); + // console.log(res.response.docs); + // console.log(res.response.numFound); // Update results this.results = res.response.docs; @@ -242,6 +255,8 @@ export default class SearchViewComponent extends Vue { // Method to handle pagination onMenuClick(page: number) { + console.log("onMenuClick"); + this.pagination.currentPage = page; const start = page * this.pagination.perPage - this.pagination.perPage; @@ -259,14 +274,19 @@ export default class SearchViewComponent extends Vue { // Method to handle facet filtering onFilter(facetItem: FacetItem): void { + console.log("onFilter"); + // Reset current page this.pagination.currentPage = 1; - // console.log(facetItem.val); + console.log(facetItem.val); + console.log(facetItem.category); + // if (!this.activeFilterCategories.hasOwnProperty(facetItem.category)) { // Check if filter item already exists if (!Object.prototype.hasOwnProperty.call(this.activeFilterCategories, facetItem.category)) { this.activeFilterCategories[facetItem.category] = new Array(); + console.log(this.activeFilterCategories); } // if (!this.activeFilterCategories[facetItem.category].some((e) => e === facetItem.val)) { @@ -279,6 +299,7 @@ export default class SearchViewComponent extends Vue { // (res: SolrResponse) => this.dataHandler(res, facetItem), // (error: string) => this.errorHandler(error), // ); + console.log(this.activeFilterCategories); DatasetService.facetedSearchOPEN(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({ next: (res: OpenSearchResponse) => this.dataHandlerOPEN(res, facetItem), error: (error: string) => this.errorHandler(error), @@ -286,60 +307,63 @@ export default class SearchViewComponent extends Vue { } } - // // Method to clear facet category filter - onClearFacetCategory(categoryName: string): void { - delete this.activeFilterCategories[categoryName]; + // // // Method to clear facet category filter + // onClearFacetCategory(categoryName: string): void { + // console.log("onClearFacetCategory"); + + // delete this.activeFilterCategories[categoryName]; - // Trigger new search with updated filter - DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({ - next: (res: SolrResponse) => { - this.results = res.response.docs; - this.numFound = res.response.numFound; + // // Trigger new search with updated filter + // DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({ + // next: (res: SolrResponse) => { + // this.results = res.response.docs; + // this.numFound = res.response.numFound; - // pagination - this.pagination["total"] = res.response.numFound; - this.pagination["perPage"] = res.responseHeader.params.rows as number; - this.pagination["currentPage"] = 1; - this.pagination["data"] = res.response.docs; + // // pagination + // this.pagination["total"] = res.response.numFound; + // this.pagination["perPage"] = res.responseHeader.params.rows as number; + // this.pagination["currentPage"] = 1; + // this.pagination["data"] = res.response.docs; - const facet_fields: FacetFields = res.facets; - let prop: keyof typeof facet_fields; - for (prop in facet_fields) { - const facetCategory: FacetInstance = facet_fields[prop]; - if (facetCategory.buckets) { - const facetItems: Array = facetCategory.buckets; + // const facet_fields: FacetFields = res.facets; + // let prop: keyof typeof facet_fields; + // for (prop in facet_fields) { + // const facetCategory: FacetInstance = facet_fields[prop]; + // if (facetCategory.buckets) { + // const facetItems: Array = facetCategory.buckets; - const facetValues = facetItems.map((facetItem) => { - let rObj: FacetItem; - if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { - // console.log(facetValue + " is included") - // Update existing facet item with new count - const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); - // console.log(indexOfFacetValue); - rObj = this.facets[prop][indexOfFacetValue]; - rObj.count = facetItem.count; - // rObj = new FacetItem(val, count); - // if facet ccategory is reactivated category, deactivate all filter items - if (prop == categoryName) { - rObj.active = false; - } - } else { - // Create new facet item - rObj = new FacetItem(facetItem.val, facetItem.count); - } - return rObj; - }); - this.facets[prop] = facetValues; - } - } - }, - error: (error: string) => this.errorHandler(error), - complete: () => console.log("clear facet category completed"), - }); - } + // const facetValues = facetItems.map((facetItem) => { + // let rObj: FacetItem; + // if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { + // // console.log(facetValue + " is included") + // // Update existing facet item with new count + // const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); + // // console.log(indexOfFacetValue); + // rObj = this.facets[prop][indexOfFacetValue]; + // rObj.count = facetItem.count; + // // rObj = new FacetItem(val, count); + // // if facet ccategory is reactivated category, deactivate all filter items + // if (prop == categoryName) { + // rObj.active = false; + // } + // } else { + // // Create new facet item + // rObj = new FacetItem(facetItem.val, facetItem.count); + // } + // return rObj; + // }); + // this.facets[prop] = facetValues; + // } + // } + // }, + // error: (error: string) => this.errorHandler(error), + // complete: () => console.log("clear facet category completed"), + // }); + // } // Method to clear facet category filter onClearFacetCategoryOPEN(categoryName: string): void { + console.log("onClearFacetCategory"); delete this.activeFilterCategories[categoryName]; // Trigger new search with updated filter