Facetsearch progressed. Pending fixing onClearFacetCategoryOPEN behaviour. Facets menu doesn't work properly.

This commit is contained in:
Porras-Bernardez 2024-06-12 16:51:26 +02:00
parent a70e454cbc
commit da430d6142
6 changed files with 264 additions and 92 deletions

View file

@ -76,7 +76,7 @@ class DatasetService {
* It is used the pipe method to chain RxJS operators to the Observable returned by api.get. The map operator is used to transform the emitted items of the Observable.
*/
return api.post<OpenSearchResponse>(base, body).pipe(
tap(response => console.log("OpenSearchResponse:", response)), // Log the complete response
// tap(response => console.log("OpenSearchResponse:", response)), // Log the complete response
// tap(response => console.log("Aggre:", response.aggregations?.subjects.buckets[0])), // log the first subject of the array of subjects returned
// tap(response => console.log("Hits:", response.hits)), // log the first subject of the array of subjects returned
@ -89,58 +89,140 @@ class DatasetService {
);
}
// For the autocomplete search. Method to perform a search based on a term
public searchTerm_SOLR(term: string, solrCore: string, solrHost: string): Observable<Dataset[]> {
// SOLR endpoint
const host = "https://" + solrHost;
const path = "/solr/" + solrCore + "/select?";
const base = host + path;
// // For the autocomplete search. Method to perform a search based on a term
// public searchTerm_SOLR(term: string, solrCore: string, solrHost: string): Observable<Dataset[]> {
// // SOLR endpoint
// const host = "https://" + solrHost;
// const path = "/solr/" + solrCore + "/select?";
// const base = host + path;
//const fields = 'id,server_date_published,abstract_output,title_output,title_additional,author,subject'; // fields we want returned
const fields = [
"id",
"licence",
"server_date_published",
"abstract_output",
"title_output",
"title_additional",
"author",
"subject",
"doctype",
].toString();
// //const fields = 'id,server_date_published,abstract_output,title_output,title_additional,author,subject'; // fields we want returned
// const fields = [
// "id",
// "licence",
// "server_date_published",
// "abstract_output",
// "title_output",
// "title_additional",
// "author",
// "subject",
// "doctype",
// ].toString();
const qfFields = "title^3 author^2 subject^1";
// const qfFields = "title^3 author^2 subject^1";
const q_params = {
"0": "fl=" + fields,
q: term + "*",
defType: "edismax",
qf: qfFields,
indent: "on",
wt: "json",
};
// const q_params = {
// "0": "fl=" + fields,
// q: term + "*",
// defType: "edismax",
// qf: qfFields,
// indent: "on",
// wt: "json",
// };
// Make API call to Solr and return the result
/**
* When a GET request is made to the Solr server using the api.get<SolrResponse> method, the response received from Solr is an object that includes various details about the search results.
* One of the key properties of this response object is docs, which is an array of documents (datasets) that match the search criteria.
* It is used the pipe method to chain RxJS operators to the Observable returned by api.get. The map operator is used to transform the emitted items of the Observable.
*/
const stations = api.get<SolrResponse>(base, q_params).pipe(map((res: SolrResponse) => res.response.docs));
// // Make API call to Solr and return the result
// /**
// * When a GET request is made to the Solr server using the api.get<SolrResponse> method, the response received from Solr is an object that includes various details about the search results.
// * One of the key properties of this response object is docs, which is an array of documents (datasets) that match the search criteria.
// * It is used the pipe method to chain RxJS operators to the Observable returned by api.get. The map operator is used to transform the emitted items of the Observable.
// */
// const stations = api.get<SolrResponse>(base, q_params).pipe(map((res: SolrResponse) => res.response.docs));
// return stations;
// }
public facetedSearchOPEN(
suggestion: Suggestion | string,
activeFilterCategories: ActiveFilterCategories,
openCore: string,
openHost: string,
start?: string, // Starting page
): Observable<OpenSearchResponse> {
// OpenSearch endpoint
const host = "https://" + openHost;
const path = "/" + openCore + "/_search";
const base = host + path;
const lowercaseTerm = typeof suggestion === 'string' ? suggestion.toLowerCase() : suggestion.value.toLowerCase();
console.log("facetedsearchOPEN > suggestion entered:");
console.log(suggestion);
/**
* The query construction depends on whether the suggestion is a string or a Suggestion object. */
// When suggestion is a string:
const query = typeof suggestion === 'string'
? {
bool: {
should: [
{ match: { title: { query: suggestion, fuzziness: "AUTO", boost: 3 } } },
{ match: { author: { query: suggestion, fuzziness: "AUTO", boost: 2 } } },
{ match: { subjects: { query: suggestion, fuzziness: "AUTO", boost: 1 } } },
{ wildcard: { title: { value: `${lowercaseTerm}*`, boost: 3 } } },
{ wildcard: { author: { value: `${lowercaseTerm}*`, boost: 2 } } },
{ wildcard: { subjects: { value: `${lowercaseTerm}*`, boost: 1 } } }
],
minimum_should_match: 1
}
}
// When suggestion is a suggestion object
: {
match: {
[suggestion.type.toLowerCase()]: {
query: suggestion.value,
operator: 'and' // all the terms in the query must be present in the field
}
}
};
// Constructing Filters Based on Active Filter Categories
const filters = Object.entries(activeFilterCategories).map(([category, values]) => ({
terms: { [`${category}.keyword`]: values }
// terms: { [category]: values }
}));
const body = {
query: {
bool: {
must: query, // Contains the main query constructed earlier.
filter: filters // Contains the filters constructed from activeFilterCategories.
}
},
size: 10,
from: start ? parseInt(start) : 0,
sort: [{ _score: { order: "desc" } }],
track_scores: true,
aggs: { // Defines aggregations for facets
// 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
// 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 } },
language: { terms: { field: "language.keyword" } },
author: { terms: { field: "author.keyword", size: 1000 } },
year: { terms: { field: "year.keyword", size: 100 } }
},
highlight: {
fields: {
title: {},
author: {},
subjects: {}
}
}
};
// 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);
return stations;
}
/* E.g. Only one facet => Author: Coric, Stjepan (16)
https://tethys.at/solr/rdr_data/select?&0=fl%3Did%2Clicence%2Cserver_date_published%2Cabstract_output%2Cidentifier%2Ctitle_output%2Ctitle_additional%2Cauthor%2Csubject%2Cdoctype&q=%2A
&q.op=or&defType=edismax&qf=title%5E3%20author%5E2%20subject%5E1&indent=on&wt=json&rows=10&fq=author%3A%28%22Coric%2C%20Stjepan%22%29&start=0&sort=server_date_published%20desc&facet=on
&json.facet.language=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22language%22%20%7D
&json.facet.subject=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22subject%22%2C%20limit%3A%20-1%20%7D
&json.facet.year=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22year%22%20%7D
&json.facet.author=%7B%20type%3A%20%22terms%22%2C%20field%3A%20%22author_facet%22%2C%20limit%3A%20-1%20%7D */
/**
* This method performs a faceted search on a Solr core. Faceted search allows the user to filter search results based on various categories (facets)
*/
@ -157,6 +239,9 @@ class DatasetService {
// console.log(solrHost);
// console.log(start);
console.log("facetedsearchSOLR > suggestion entered:");
console.log(suggestion);
// Construct Solr query parameters
const host = "https://" + solrHost;
const path = "/solr/" + solrCore + "/select?";