Fixing facetedsearch

This commit is contained in:
Porras-Bernardez 2024-06-19 11:12:53 +02:00
parent d135ab2d50
commit 95c7c8ba7b
8 changed files with 246 additions and 210 deletions

View File

@ -20,7 +20,7 @@ export default class FacetCategory extends Vue {
filterName!: string; filterName!: string;
get alias(): string { get alias(): string {
console.log("filterName:", this.filterName); // console.log("filterName:", this.filterName);
return this.filterName == "datatype" ? "doctype" : this.filterName; return this.filterName == "datatype" ? "doctype" : this.filterName;
} }
@ -54,7 +54,7 @@ export default class FacetCategory extends Vue {
@Emit("filter") @Emit("filter")
activateItem(filterItem: FacetItem): FacetItem { activateItem(filterItem: FacetItem): FacetItem {
// console.log(filterItem); // console.log("ActivateItem");
filterItem.category = this.alias; filterItem.category = this.alias;
filterItem.active = true; filterItem.active = true;
// this.$emit("filter", filterItem); // this.$emit("filter", filterItem);

View File

@ -8,9 +8,6 @@
<!-- e.g.language --> <!-- e.g.language -->
<ul class="filter-items list-unstyled" v-bind:class="{ limited: facetItems.length > 1 && collapsed }"> <ul class="filter-items list-unstyled" v-bind:class="{ limited: facetItems.length > 1 && collapsed }">
<li v-for="(item, index) in facetItems" v-bind:key="index" class="list-group-item titlecase"> <li v-for="(item, index) in facetItems" v-bind:key="index" class="list-group-item titlecase">
{{ item.active }}
{{ item.val }}
{{ item.count }} //
<!-- <span :class="item.Active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.val }} ({{ item.count }}) </span> --> <!-- <span :class="item.Active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.val }} ({{ item.count }}) </span> -->
<span v-bind:class="item.active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.val }} ({{ item.count }}) </span> <span v-bind:class="item.active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.val }} ({{ item.count }}) </span>
</li> </li>

View File

@ -2,12 +2,12 @@
// import debounce from 'lodash/debounce'; // import debounce from 'lodash/debounce';
// import { DatasetService } from "../../services/dataset.service"; // import { DatasetService } from "../../services/dataset.service";
import DatasetService from "../../services/dataset.service"; import DatasetService from "../../services/dataset.service";
import { SolrSettings } from "@/models/solr"; // PENDING USE // import { SolrSettings } from "@/models/solr"; // PENDING USE
import { OpenSettings } from "@/models/solr"; import { OpenSettings } from "@/models/solr";
import { Component, Vue, Prop, Emit } from "vue-facing-decorator"; import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
import { Dataset, Suggestion, SearchType } from "@/models/dataset"; import { Dataset, Suggestion, SearchType } from "@/models/dataset";
import { SOLR_HOST, SOLR_CORE } from "@/constants"; // import { SOLR_HOST, SOLR_CORE } from "@/constants";
import { OPEN_HOST, OPEN_CORE } from "@/constants"; // PENDING USE import { OPEN_HOST, OPEN_CORE } from "@/constants"; // PENDING USE
import { HitHighlight } from "@/models/headers"; import { HitHighlight } from "@/models/headers";
@ -38,10 +38,10 @@ export default class VsInput extends Vue {
private loading = false; // Loading state indicator private loading = false; // Loading state indicator
private selectedIndex = -1; // Index of the currently selected suggestion private selectedIndex = -1; // Index of the currently selected suggestion
private solr: SolrSettings = { // private solr: SolrSettings = {
core: SOLR_CORE, //"rdr_data", // SOLR.core; // core: SOLR_CORE, //"rdr_data", // SOLR.core;
host: SOLR_HOST, //"tethys.at", // host: SOLR_HOST, //"tethys.at",
}; // };
private openSearch: OpenSettings = { private openSearch: OpenSettings = {
core: OPEN_CORE, //"rdr_data", // SOLR.core; core: OPEN_CORE, //"rdr_data", // SOLR.core;

View File

@ -2,8 +2,8 @@
// declare const EDGE_URL: string; // declare const EDGE_URL: string;
declare const APP_URL: string; declare const APP_URL: string;
declare const VUE_API: string; declare const VUE_API: string;
declare const SOLR_HOST: string; // declare const SOLR_HOST: string;
declare const SOLR_CORE: string; // declare const SOLR_CORE: string;
// OPENSEARCH // OPENSEARCH
declare const OPEN_HOST: string; declare const OPEN_HOST: string;
@ -13,8 +13,8 @@ declare const OPEN_CORE: string;
// const _POINT_URL = POINT_URL; // const _POINT_URL = POINT_URL;
const _APP_URL = APP_URL; const _APP_URL = APP_URL;
const _VUE_API = VUE_API; const _VUE_API = VUE_API;
const _SOLR_HOST = SOLR_HOST; // const _SOLR_HOST = SOLR_HOST;
const _SOLR_CORE = SOLR_CORE; // const _SOLR_CORE = SOLR_CORE;
// OPENSEARCH // OPENSEARCH
const _OPEN_HOST = OPEN_HOST; const _OPEN_HOST = OPEN_HOST;
@ -24,8 +24,8 @@ const _OPEN_CORE = OPEN_CORE;
// export { _POINT_URL as POINT_URL }; // export { _POINT_URL as POINT_URL };
export { _APP_URL as APP_URL }; export { _APP_URL as APP_URL };
export { _VUE_API as VUE_API }; export { _VUE_API as VUE_API };
export { _SOLR_HOST as SOLR_HOST }; // export { _SOLR_HOST as SOLR_HOST };
export { _SOLR_CORE as SOLR_CORE }; // export { _SOLR_CORE as SOLR_CORE };
// OPENSEARCH // OPENSEARCH
export { _OPEN_HOST as OPEN_HOST }; export { _OPEN_HOST as OPEN_HOST };

View File

@ -1,7 +1,7 @@
export interface SolrSettings { // export interface SolrSettings {
core: string; // core: string;
host: string; // host: string;
} // }
export interface OpenSettings { export interface OpenSettings {
core: string; core: string;

View File

@ -26,11 +26,10 @@ class DatasetService {
// private openSearchUrl = "http://opensearch.geoinformation.dev/tethys-records/_search"; // private openSearchUrl = "http://opensearch.geoinformation.dev/tethys-records/_search";
// private openSearchUrl = "http://192.168.21.18/tethys-records/_search"; // private openSearchUrl = "http://192.168.21.18/tethys-records/_search";
// public searchTerm(term: string): Observable<Dataset[]> {
public searchTerm(term: string, openCore: string, openHost: string): Observable<{ datasets: Dataset[], highlights: HitHighlight[] }> { public searchTerm(term: string, openCore: string, openHost: string): Observable<{ datasets: Dataset[], highlights: HitHighlight[] }> {
// OpenSearch endpoint // OpenSearch endpoint
const host = "https://" + openHost; // When using geoinformation.dev // const host = "https://" + openHost; // When using geoinformation.dev
// const host = "http://" + openHost; // When using local OpenSearch dev endpoint const host = "http://" + openHost; // When using local OpenSearch dev endpoint
const path = "/" + openCore + "/_search"; const path = "/" + openCore + "/_search";
const base = host + path; const base = host + path;
/** /**
@ -57,8 +56,10 @@ class DatasetService {
sort: [{ _score: { order: "desc" } }], // Sort by _score in descending order sort: [{ _score: { order: "desc" } }], // Sort by _score in descending order
track_scores: true, // This ensures "_score" is included even when sorting by other criteria. Otherwise the relevance score is not calculated track_scores: true, // This ensures "_score" is included even when sorting by other criteria. Otherwise the relevance score is not calculated
aggs: { aggs: {
language: { terms: { field: "language.keyword" } }, subjects: { terms: { field: "subjects.keyword", size: 1000 } }, // In SOLR is "subject"!
subjects: { terms: { field: "subjects.keyword", size: 10 } } // In SOLR is "subject"! language: { terms: { field: "language" } }, // << ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS
author: { terms: { field: "author.keyword", size: 1000 } },
year: { terms: { field: "year", size: 100 } } // << ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS
}, },
highlight: { highlight: {
fields: { fields: {
@ -69,6 +70,8 @@ class DatasetService {
} }
}; };
// Make API call to OpenSearch and return the result // Make API call to OpenSearch and return the result
/** /**
* When a POST request is made to the OpenSearch server using the api.post<OpenSearchResponse> method, the response received from OpenSearch is an object that includes various details about the search results. * When a POST request is made to the OpenSearch server using the api.post<OpenSearchResponse> method, the response received from OpenSearch is an object that includes various details about the search results.
@ -140,7 +143,8 @@ class DatasetService {
start?: string, // Starting page start?: string, // Starting page
): Observable<OpenSearchResponse> { ): Observable<OpenSearchResponse> {
// OpenSearch endpoint // OpenSearch endpoint
const host = "https://" + openHost; // const host = "https://" + openHost; // When using geoinformation.dev
const host = "http://" + openHost; // When using local OpenSearch dev endpoint
const path = "/" + openCore + "/_search"; const path = "/" + openCore + "/_search";
const base = host + path; const base = host + path;
@ -179,10 +183,17 @@ class DatasetService {
}; };
// Constructing Filters Based on Active Filter Categories // Constructing Filters Based on Active Filter Categories
const filters = Object.entries(activeFilterCategories).map(([category, values]) => ({ // const filters = Object.entries(activeFilterCategories).map(([category, values]) => ({
terms: { [`${category}.keyword`]: values } // terms: { [`${category}.keyword`]: values }
// terms: { [category]: values } // // terms: { [category]: values }
})); // }));
const filters = Object.entries(activeFilterCategories).map(([category, values]) => {
if (category === "language" || category === "year") {
return { terms: { [category]: values } };
} else {
return { terms: { [`${category}.keyword`]: values } };
}
});
const body = { const body = {
query: { query: {
@ -199,10 +210,10 @@ class DatasetService {
// terms: Aggregation type that returns the most common terms in a field. // terms: Aggregation type that returns the most common terms in a field.
// !For a large number of terms setting an extremely large size might not be efficient // !For a large number of terms setting an extremely large size might not be efficient
// If you genuinely need all unique terms and expect a large number of them, consider using a composite aggregation for more efficient pagination of terms. // If you genuinely need all unique terms and expect a large number of them, consider using a composite aggregation for more efficient pagination of terms.
subjects: { terms: { field: "subjects.keyword", size: 1000 } }, subjects: { terms: { field: "subjects.keyword", size: 1000 } }, // In SOLR is "subject"!
language: { terms: { field: "language.keyword" } }, language: { terms: { field: "language" } }, // ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS
author: { terms: { field: "author.keyword", size: 1000 } }, author: { terms: { field: "author.keyword", size: 1000 } },
year: { terms: { field: "year.keyword", size: 100 } } year: { terms: { field: "year", size: 100 } } // ".keyword" HAS TO BE REMOVED. OTHERWISE BUCKETS ARE NOT OBTAINED FOR THIS
}, },
highlight: { highlight: {
fields: { fields: {
@ -213,126 +224,119 @@ class DatasetService {
} }
}; };
// return api.post<OpenSearchResponse>(base, body).pipe(
// // map(response => ({
// // datasets: response.hits.hits.map(hit => hit._source),
// // highlights: response.hits.hits.map(hit => hit.highlight),
// // // aggregations: response.aggregations
// // }))
// );
const stations = api.post<OpenSearchResponse>(base, body); const stations = api.post<OpenSearchResponse>(base, body);
return stations; return stations;
} }
/** // /**
* This method performs a faceted search on a Solr core. Faceted search allows the user to filter search results based on various categories (facets) // * This method performs a faceted search on a Solr core. Faceted search allows the user to filter search results based on various categories (facets)
*/ // */
public facetedSearch( // public facetedSearch_SOLR(
suggestion: Suggestion | string, // suggestion: Suggestion | string,
activeFilterCategories: ActiveFilterCategories, // activeFilterCategories: ActiveFilterCategories,
solrCore: string, // solrCore: string,
solrHost: string, // solrHost: string,
start?: string, // Starting page // start?: string, // Starting page
): Observable<SolrResponse> { // ): Observable<SolrResponse> {
// console.log("face:", suggestion); // // console.log("face:", suggestion);
// console.log(activeFilterCategories); // // console.log(activeFilterCategories);
// console.log(solrCore); // // console.log(solrCore);
// console.log(solrHost); // // console.log(solrHost);
// console.log(start); // // console.log(start);
console.log("facetedsearchSOLR > suggestion entered:"); // console.log("facetedsearchSOLR > suggestion entered:");
console.log(suggestion); // console.log(suggestion);
// Construct Solr query parameters // // Construct Solr query parameters
const host = "https://" + solrHost; // const host = "https://" + solrHost;
const path = "/solr/" + solrCore + "/select?"; // const path = "/solr/" + solrCore + "/select?";
const base = host + path; // const base = host + path;
const fields = [ // const fields = [
"id", // "id",
"licence", // "licence",
"server_date_published", // "server_date_published",
"abstract_output", // "abstract_output",
"identifier", // "identifier",
"title_output", // "title_output",
"title_additional", // "title_additional",
"author", // "author",
"subject", // "subject",
"doctype", // "doctype",
].toString(); // ].toString();
// Determine search term, query operator, and query fields based on the suggestion type. Depending on whether suggestion is a string or a Suggestion object, it constructs the search term and query fields differently. // // Determine search term, query operator, and query fields based on the suggestion type. Depending on whether suggestion is a string or a Suggestion object, it constructs the search term and query fields differently.
let term, queryOperator, qfFields; // let term, queryOperator, qfFields;
if (typeof suggestion === "string") { // f suggestion is a string, it appends a wildcard (*) for partial matches. // if (typeof suggestion === "string") { // f suggestion is a string, it appends a wildcard (*) for partial matches.
term = suggestion + "*"; // term = suggestion + "*";
queryOperator = "or"; // queryOperator = "or";
qfFields = "title^3 author^2 subject^1"; // qfFields = "title^3 author^2 subject^1";
} else if (suggestion instanceof Suggestion) { // If suggestion is a Suggestion object, it forms a more specific query based on the type and value of the suggestion. // } else if (suggestion instanceof Suggestion) { // If suggestion is a Suggestion object, it forms a more specific query based on the type and value of the suggestion.
term = suggestion.type + ':"' + suggestion.value + '"'; // term = suggestion.type + ':"' + suggestion.value + '"';
queryOperator = "and"; // queryOperator = "and";
qfFields = undefined; // qfFields = undefined;
} // }
// Set default value for start if not provided // // Set default value for start if not provided
if (start === undefined) start = "0"; // if (start === undefined) start = "0";
// Construct filter fields based on active filter categories // // Construct filter fields based on active filter categories
const filterFields = new Array<string>(); // const filterFields = new Array<string>();
if (Object.keys(activeFilterCategories).length > 0) { // if (Object.keys(activeFilterCategories).length > 0) {
/* Declare variable prop with a type that is a key of the activeFilterCategories. The 'keyof typeof' activeFilterCategories type represents all possible keys // /* Declare variable prop with a type that is a key of the activeFilterCategories. The 'keyof typeof' activeFilterCategories type represents all possible keys
that can exist on the activeFilterCategories --> prop can only be assigned a value that is a key of the activeFilterCategories object */ // that can exist on the activeFilterCategories --> prop can only be assigned a value that is a key of the activeFilterCategories object */
let prop: keyof typeof activeFilterCategories; // let prop: keyof typeof activeFilterCategories;
for (prop in activeFilterCategories) { // for (prop in activeFilterCategories) {
const filterItems = activeFilterCategories[prop]; // const filterItems = activeFilterCategories[prop];
filterItems.forEach(function (value: string) { // filterItems.forEach(function (value: string) {
filterFields.push(prop + ':("' + value + '")'); // filterFields.push(prop + ':("' + value + '")');
// e.g. Array [ 'subject:("Vektordaten")', 'author:("GeoSphere Austria, ")' ] // // e.g. Array [ 'subject:("Vektordaten")', 'author:("GeoSphere Austria, ")' ]
}); // });
} // }
} // }
// https://solr.apache.org/guide/8_4/json-request-api.html // // https://solr.apache.org/guide/8_4/json-request-api.html
// Construct Solr query parameters // // Construct Solr query parameters
const q_params = { // const q_params = {
"0": "fl=" + fields, // "0": "fl=" + fields,
q: term, // q: term,
"q.op": queryOperator, // "q.op": queryOperator,
defType: "edismax", // defType: "edismax",
qf: qfFields, // qf: qfFields,
// df: "title", // // df: "title",
indent: "on", // indent: "on",
wt: "json", // wt: "json",
rows: 10, // rows: 10,
// fq: ["subject:Steiermark", "language:de"], // // fq: ["subject:Steiermark", "language:de"],
fq: filterFields, // fq: filterFields,
start: start, // start: start,
sort: "server_date_published desc", // sort: "server_date_published desc",
facet: "on", // facet: "on",
// "facet.field": "language", // // "facet.field": "language",
"json.facet.language": '{ type: "terms", field: "language" }', // "json.facet.language": '{ type: "terms", field: "language" }',
"json.facet.subject": '{ type: "terms", field: "subject", limit: -1 }', // "json.facet.subject": '{ type: "terms", field: "subject", limit: -1 }',
"json.facet.year": '{ type: "terms", field: "year" }', // "json.facet.year": '{ type: "terms", field: "year" }',
"json.facet.author": '{ type: "terms", field: "author_facet", limit: -1 }', // "json.facet.author": '{ type: "terms", field: "author_facet", limit: -1 }',
}; // };
/* E.g. // /* E.g.
{"0":"fl=id,licence,server_date_published,abstract_output,identifier,title_output,title_additional,author,subject,doctype","q":"*","q.op":"or","defType":"edismax", // {"0":"fl=id,licence,server_date_published,abstract_output,identifier,title_output,title_additional,author,subject,doctype","q":"*","q.op":"or","defType":"edismax",
"qf":"title^3 author^2 subject^1", // "qf":"title^3 author^2 subject^1",
"indent":"on","wt":"json","rows":10, // "indent":"on","wt":"json","rows":10,
"fq":["subject:(\"Vektordaten\")","author:(\"GeoSphere Austria, \")"], // "fq":["subject:(\"Vektordaten\")","author:(\"GeoSphere Austria, \")"],
"start":"0","sort":"server_date_published desc","facet":"on", // "start":"0","sort":"server_date_published desc","facet":"on",
"json.facet.language":"{ type: \"terms\", field: \"language\" }", // "json.facet.language":"{ type: \"terms\", field: \"language\" }",
"json.facet.subject":"{ type: \"terms\", field: \"subject\", limit: -1 }", // "json.facet.subject":"{ type: \"terms\", field: \"subject\", limit: -1 }",
"json.facet.year":"{ type: \"terms\", field: \"year\" }", // "json.facet.year":"{ type: \"terms\", field: \"year\" }",
"json.facet.author":"{ type: \"terms\", field: \"author_facet\", limit: -1 }"} // "json.facet.author":"{ type: \"terms\", field: \"author_facet\", limit: -1 }"}
*/ // */
// console.log(JSON.stringify(q_params)); // // console.log(JSON.stringify(q_params));
// Make API call to Solr and return the result // // Make API call to Solr and return the result
const stations = api.get<SolrResponse>(base, q_params); // const stations = api.get<SolrResponse>(base, q_params);
return stations; // return stations;
} // }
// Method to fetch years // Method to fetch years
public getYears(): Observable<string[]> { public getYears(): Observable<string[]> {

View File

@ -3,16 +3,17 @@ import VsInput from "@/components/vs-input/vs-input.vue";
import VsResult from "@/components/vs-result/vs-result.vue"; import VsResult from "@/components/vs-result/vs-result.vue";
import FacetCategory from "@/components/face-category/facet-category.vue"; import FacetCategory from "@/components/face-category/facet-category.vue";
import ActiveFacetCategory from "@/components/active-facet-category/active-facet-category.vue"; import ActiveFacetCategory from "@/components/active-facet-category/active-facet-category.vue";
import { SolrSettings } from "@/models/solr"; // import { SolrSettings } from "@/models/solr";
import { OpenSettings } from "@/models/solr"; import { OpenSettings } from "@/models/solr";
// import { DatasetService } from "@/services/dataset.service"; // import { DatasetService } from "@/services/dataset.service";
import DatasetService from "../../services/dataset.service"; import DatasetService from "../../services/dataset.service";
import { Suggestion, Dataset, SearchType } from "@/models/dataset"; import { Suggestion, Dataset, SearchType } from "@/models/dataset";
// import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance } from "@/models/headers"; // import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance } from "@/models/headers";
import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance, OpenSearchResponse, HitHighlight } from "@/models/headers"; // import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance, OpenSearchResponse, HitHighlight } from "@/models/headers";
import { FacetFields, FacetItem, FacetResults, FacetInstance, OpenSearchResponse, HitHighlight } from "@/models/headers";
import { ActiveFilterCategories } from "@/models/solr"; import { ActiveFilterCategories } from "@/models/solr";
import { SOLR_HOST, SOLR_CORE } from "@/constants"; // import { SOLR_HOST, SOLR_CORE } from "@/constants";
import { IPagination } from "@/models/pagination"; import { IPagination } from "@/models/pagination";
import PaginationComponent from "@/components/PaginationComponent.vue"; import PaginationComponent from "@/components/PaginationComponent.vue";
@ -54,10 +55,10 @@ export default class SearchViewComponent extends Vue {
}; };
loaded = false; loaded = false;
numFound!: number; numFound!: number;
private solr: SolrSettings = { // private solr: SolrSettings = {
core: SOLR_CORE, //"rdr_data", // SOLR.core; // core: SOLR_CORE, //"rdr_data", // SOLR.core;
host: SOLR_HOST, //"tethys.at", // host: SOLR_HOST, //"tethys.at",
}; // };
private open: OpenSettings = { private open: OpenSettings = {
core: OPEN_CORE, //"rdr_data", // SOLR.core; core: OPEN_CORE, //"rdr_data", // SOLR.core;
@ -157,6 +158,8 @@ export default class SearchViewComponent extends Vue {
// console.log(this.numFound); // console.log(this.numFound);
// console.log(res.hits.hits); // console.log(res.hits.hits);
// console.log(res.hits.total.value); // console.log(res.hits.total.value);
console.log(res);
// for (const key in this.results) { // for (const key in this.results) {
// if (Object.prototype.hasOwnProperty.call(this.results, key)) { // if (Object.prototype.hasOwnProperty.call(this.results, key)) {
@ -172,81 +175,113 @@ export default class SearchViewComponent extends Vue {
this.pagination.data = this.results; this.pagination.data = this.results;
this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage); this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage);
// if (res.aggregations) {
// const facet_fields = res.aggregations;
// let prop: keyof typeof facet_fields;
// for (prop in facet_fields) {
// const facetCategory = facet_fields[prop];
// if (facetCategory.buckets) {
// const facetItems = facetCategory.buckets.map(bucket => new FacetItem(bucket.key, bucket.doc_count));
// this.facets[prop] = facetItems.filter(el => el.count > 0);
// }
// }
// }
if (res.aggregations) { if (res.aggregations) {
const facet_fields = res.aggregations; const facet_fields = res.aggregations;
let prop: keyof typeof facet_fields; let prop: keyof typeof facet_fields;
// Iterate through facet fields
for (prop in facet_fields) { for (prop in facet_fields) {
const facetCategory = facet_fields[prop]; const facetCategory = facet_fields[prop];
if (facetCategory.buckets) { if (facetCategory.buckets) {
const facetItems = facetCategory.buckets.map(bucket => new FacetItem(bucket.key, bucket.doc_count)); const facetItems = facetCategory.buckets.map(bucket => new FacetItem(bucket.key, bucket.doc_count));
this.facets[prop] = facetItems.filter(el => el.count > 0); let facetValues = facetItems.map((facetItem) => {
let rObj: FacetItem;
// Check if current facet item matches filter item
if (filterItem?.val == facetItem.val) {
rObj = filterItem;
} else if (this.facets[prop]?.some((e) => e.val === facetItem.val)) {
const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val);
rObj = this.facets[prop][indexOfFacetValue];
rObj.count = facetItem.count;
} else {
// Create new facet item
rObj = new FacetItem(facetItem.val, facetItem.count);
}
return rObj;
});
// Filter out null values and values with count <= 0
facetValues = facetValues.filter(el => el.count > 0);
this.facets[prop] = facetValues;
} }
} }
} }
} }
// Method to handle search response // // Method to handle search response
private dataHandler(res: SolrResponse, filterItem?: FacetItem): void { // private dataHandler(res: SolrResponse, filterItem?: FacetItem): void {
// console.log("dataHandlerSOLR (docs, numFound):"); // // console.log("dataHandlerSOLR (docs, numFound):");
// console.log(res.response.docs); // // console.log(res.response.docs);
// console.log(res.response.numFound); // // console.log(res.response.numFound);
// Update results // // Update results
this.results = res.response.docs; // this.results = res.response.docs;
this.numFound = res.response.numFound; // this.numFound = res.response.numFound;
// Update pagination // // Update pagination
this.pagination["total"] = res.response.numFound; // this.pagination["total"] = res.response.numFound;
this.pagination["perPage"] = res.responseHeader.params.rows as number; // this.pagination["perPage"] = res.responseHeader.params.rows as number;
this.pagination["data"] = res.response.docs; // this.pagination["data"] = res.response.docs;
this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage); // this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage);
const facet_fields: FacetFields = res.facets; // const facet_fields: FacetFields = res.facets;
/* This code declares a variable prop with a type of keys of the facet_fields object. The keyof typeof facet_fields type represents the keys of the facet_fields object. // /* This code declares a variable prop with a type of keys of the facet_fields object. The keyof typeof facet_fields type represents the keys of the facet_fields object.
This means that prop can only hold values that are keys of the facet_fields object. */ // This means that prop can only hold values that are keys of the facet_fields object. */
let prop: keyof typeof facet_fields; // let prop: keyof typeof facet_fields;
// Iterate through facet fields // // Iterate through facet fields
for (prop in facet_fields) { // for (prop in facet_fields) {
const facetCategory = facet_fields[prop]; // const facetCategory = facet_fields[prop];
if (facetCategory.buckets) { // if (facetCategory.buckets) {
const facetItems: Array<FacetItem> = facetCategory.buckets; // const facetItems: Array<FacetItem> = facetCategory.buckets;
let facetValues = facetItems.map((facetItem) => { // let facetValues = facetItems.map((facetItem) => {
let rObj: FacetItem; // let rObj: FacetItem;
// Check if current facet item matches filter item // // Check if current facet item matches filter item
if (filterItem?.val == facetItem.val) { // if (filterItem?.val == facetItem.val) {
rObj = filterItem; // rObj = filterItem;
} else if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { // } else if (this.facets[prop]?.some((e) => e.val === facetItem.val)) {
// console.log(facetValue + " is included") // // console.log(facetValue + " is included")
// Update existing facet item with new count // // Update existing facet item with new count
const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); // const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val);
// console.log(indexOfFacetValue); // // console.log(indexOfFacetValue);
rObj = this.facets[prop][indexOfFacetValue]; // rObj = this.facets[prop][indexOfFacetValue];
rObj.count = facetItem.count; // rObj.count = facetItem.count;
// rObj = new FacetItem(val, count); // // rObj = new FacetItem(val, count);
} else { // } else {
// Create new facet item // // Create new facet item
rObj = new FacetItem(facetItem.val, facetItem.count); // rObj = new FacetItem(facetItem.val, facetItem.count);
} // }
return rObj; // return rObj;
}); // });
// Filter out null values and values with count <= 0 // // Filter out null values and values with count <= 0
facetValues = facetValues.filter(function (el) { // facetValues = facetValues.filter(function (el) {
return el != null && el.count > 0; // return el != null && el.count > 0;
}); // });
// this.facets[prop] = facetCategory; // // this.facets[prop] = facetCategory;
// Update facet values // // Update facet values
this.facets[prop] = facetValues; // this.facets[prop] = facetValues;
} // }
} // }
} // }
// Method to handle search errors // Method to handle search errors
private errorHandler(err: string): void { private errorHandler(err: string): void {
@ -278,15 +313,15 @@ export default class SearchViewComponent extends Vue {
// Reset current page // Reset current page
this.pagination.currentPage = 1; this.pagination.currentPage = 1;
console.log(facetItem.val); // console.log(facetItem.val);
console.log(facetItem.category); // console.log(facetItem.category);
// if (!this.activeFilterCategories.hasOwnProperty(facetItem.category)) { // if (!this.activeFilterCategories.hasOwnProperty(facetItem.category)) {
// Check if filter item already exists // Check if filter item already exists
if (!Object.prototype.hasOwnProperty.call(this.activeFilterCategories, facetItem.category)) { if (!Object.prototype.hasOwnProperty.call(this.activeFilterCategories, facetItem.category)) {
this.activeFilterCategories[facetItem.category] = new Array<string>(); this.activeFilterCategories[facetItem.category] = new Array<string>();
console.log(this.activeFilterCategories); // console.log(this.activeFilterCategories);
} }
// if (!this.activeFilterCategories[facetItem.category].some((e) => e === facetItem.val)) { // if (!this.activeFilterCategories[facetItem.category].some((e) => e === facetItem.val)) {
@ -299,7 +334,7 @@ export default class SearchViewComponent extends Vue {
// (res: SolrResponse) => this.dataHandler(res, facetItem), // (res: SolrResponse) => this.dataHandler(res, facetItem),
// (error: string) => this.errorHandler(error), // (error: string) => this.errorHandler(error),
// ); // );
console.log(this.activeFilterCategories); // console.log(this.activeFilterCategories);
DatasetService.facetedSearchOPEN(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({ DatasetService.facetedSearchOPEN(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({
next: (res: OpenSearchResponse) => this.dataHandlerOPEN(res, facetItem), next: (res: OpenSearchResponse) => this.dataHandlerOPEN(res, facetItem),
error: (error: string) => this.errorHandler(error), error: (error: string) => this.errorHandler(error),
@ -363,7 +398,7 @@ export default class SearchViewComponent extends Vue {
// Method to clear facet category filter // Method to clear facet category filter
onClearFacetCategoryOPEN(categoryName: string): void { onClearFacetCategoryOPEN(categoryName: string): void {
console.log("onClearFacetCategory"); // console.log("onClearFacetCategory");
delete this.activeFilterCategories[categoryName]; delete this.activeFilterCategories[categoryName];
// Trigger new search with updated filter // Trigger new search with updated filter

View File

@ -89,8 +89,8 @@ module.exports = {
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false", __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false",
APP_URL: JSON.stringify(process.env.APP_URL), APP_URL: JSON.stringify(process.env.APP_URL),
VUE_API: JSON.stringify(process.env.VUE_API), VUE_API: JSON.stringify(process.env.VUE_API),
SOLR_HOST: JSON.stringify(process.env.SOLR_HOST), // SOLR_HOST: JSON.stringify(process.env.SOLR_HOST),
SOLR_CORE: JSON.stringify(process.env.SOLR_CORE), // SOLR_CORE: JSON.stringify(process.env.SOLR_CORE),
// OPENSEARCH // OPENSEARCH
OPEN_HOST: JSON.stringify(process.env.OPEN_HOST), OPEN_HOST: JSON.stringify(process.env.OPEN_HOST),
OPEN_CORE: JSON.stringify(process.env.OPEN_CORE), OPEN_CORE: JSON.stringify(process.env.OPEN_CORE),