forked from geolba/tethys.frontend
OpenSearch progress. Stetic changes in result list. Faceted search not started
This commit is contained in:
parent
9b8b2bd5ac
commit
a70e454cbc
|
@ -1,4 +1,6 @@
|
|||
APP_URL=//tethys.at
|
||||
VUE_API=//www.tethys.at
|
||||
SOLR_HOST=tethys.at
|
||||
SOLR_CORE=rdr_data
|
||||
# SOLR_HOST=tethys.at
|
||||
# SOLR_CORE=rdr_data
|
||||
OPEN_HOST=192.168.21.18
|
||||
OPEN_CORE=tethys-records
|
|
@ -37,15 +37,13 @@ export default class VsInput extends Vue {
|
|||
|
||||
private loading = false; // Loading state indicator
|
||||
private selectedIndex = -1; // Index of the currently selected suggestion
|
||||
// private selectedDisplay = "";
|
||||
|
||||
private solr: SolrSettings = {
|
||||
core: SOLR_CORE, //"rdr_data", // SOLR.core;
|
||||
host: SOLR_HOST, //"tethys.at",
|
||||
// core: "test_data", // SOLR.core;
|
||||
// host: "repository.geologie.ac.at",
|
||||
};
|
||||
|
||||
private open: OpenSettings = {
|
||||
private openSearch: OpenSettings = {
|
||||
core: OPEN_CORE, //"rdr_data", // SOLR.core;
|
||||
host: OPEN_HOST, //"tethys.at",
|
||||
// core: "test_data", // SOLR.core;
|
||||
|
@ -126,7 +124,7 @@ export default class VsInput extends Vue {
|
|||
if (highlight.author && highlight.author.length > 0) {
|
||||
const highlightedAuthor = highlight.author.join(" ");
|
||||
const datasetAuthor = this.find(dataset.author, this.display.toLowerCase());
|
||||
const hasAuthorSuggestion = suggestions.some((suggestion) => suggestion.highlight === highlightedAuthor && suggestion.type == SearchType.Author);
|
||||
const hasAuthorSuggestion = suggestions.some((suggestion) => suggestion.highlight.toLowerCase() === highlightedAuthor.toLowerCase() && suggestion.type == SearchType.Author);
|
||||
if (!hasAuthorSuggestion) {
|
||||
const suggestion = new Suggestion(datasetAuthor, highlightedAuthor, SearchType.Author);
|
||||
suggestions.push(suggestion);
|
||||
|
@ -135,48 +133,13 @@ export default class VsInput extends Vue {
|
|||
if (highlight.subjects && highlight.subjects.length > 0) {
|
||||
const highlightedSubject = highlight.subjects.join(" ");
|
||||
const datasetSubject = this.find(dataset.subjects, this.display.toLowerCase());
|
||||
const hasSubjectSuggestion = suggestions.some((suggestion) => suggestion.highlight === highlightedSubject && suggestion.type == SearchType.Subject);
|
||||
const hasSubjectSuggestion = suggestions.some((suggestion) => suggestion.highlight.toLowerCase() === highlightedSubject.toLowerCase() && suggestion.type == SearchType.Subject);
|
||||
if (!hasSubjectSuggestion) {
|
||||
const suggestion = new Suggestion(datasetSubject, highlightedSubject, SearchType.Subject);
|
||||
suggestions.push(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
// // Checks if a suggestion with the same title and type already exists in the suggestions array. If not, it creates a new Suggestion object and adds it to the suggestions array.
|
||||
// if (highlight.title && highlight.title.length > 0) {
|
||||
// /** This line checks if the highlight object has a title property and if that property is an array with at least one element.
|
||||
// * The highlight object contains highlighted fragments of the search term in various fields (e.g., title, author, subjects) as returned by the OpenSearch API.
|
||||
// * This check ensures that we only process results that have highlighted titles. */
|
||||
// const title = highlight.title.join(" ");
|
||||
// /**
|
||||
// * The highlight.title property is an array of strings, where each string is a highlighted fragment of the title. join(" ") combines these fragments into a single string with spaces between them.
|
||||
// * This step constructs a full highlighted title from the individual fragments.
|
||||
// * OpenSearch can return multiple fragments of a field (like the title) in its response, especially when the field contains multiple terms that match the search query.
|
||||
// * This can happen because OpenSearch's highlighting feature is designed to provide context around each match within the field, which can result in multiple highlighted fragments.
|
||||
// */
|
||||
// const hasTitleSuggestion = suggestions.some((suggestion) => suggestion.value === title && suggestion.type == SearchType.Title);
|
||||
// if (!hasTitleSuggestion) {
|
||||
// const suggestion = new Suggestion(title, SearchType.Title);
|
||||
// suggestions.push(suggestion);
|
||||
// }
|
||||
// }
|
||||
// if (highlight.author && highlight.author.length > 0) {
|
||||
// const author = highlight.author.join(" ");
|
||||
// const hasAuthorSuggestion = suggestions.some((suggestion) => suggestion.value === author && suggestion.type == SearchType.Author);
|
||||
// if (!hasAuthorSuggestion) {
|
||||
// const suggestion = new Suggestion(author, SearchType.Author);
|
||||
// suggestions.push(suggestion);
|
||||
// }
|
||||
// }
|
||||
// if (highlight.subjects && highlight.subjects.length > 0) {
|
||||
// const subject = highlight.subjects.join(" ");
|
||||
// const hasSubjectSuggestion = suggestions.some((suggestion) => suggestion.value === subject && suggestion.type == SearchType.Subject);
|
||||
// if (!hasSubjectSuggestion) {
|
||||
// const suggestion = new Suggestion(subject, SearchType.Subject);
|
||||
// suggestions.push(suggestion);
|
||||
// }
|
||||
// }
|
||||
|
||||
// ORIGINAL SOLR ===================================================================================================
|
||||
// if (dataset.title_output.toLowerCase().includes(this.display.toLowerCase())) {
|
||||
// const title = dataset.title_output;
|
||||
|
@ -238,6 +201,7 @@ export default class VsInput extends Vue {
|
|||
and emits a search-change event with the current value of display as the argument. */
|
||||
@Emit("search-change")
|
||||
search(): string {
|
||||
console.log("search");
|
||||
this.results = [];
|
||||
// this.$emit("search", this.display)
|
||||
this.value = this.display; //(obj["title_output"]) ? obj["title_output"] : obj.id
|
||||
|
@ -260,6 +224,7 @@ export default class VsInput extends Vue {
|
|||
|
||||
// Perform the search request
|
||||
private resourceSearch() {
|
||||
console.log("resourceSearch");
|
||||
if (!this.display) {
|
||||
this.results = [];
|
||||
return;
|
||||
|
@ -273,7 +238,7 @@ export default class VsInput extends Vue {
|
|||
private request(): void {
|
||||
console.log("request()");
|
||||
// DatasetService.searchTerm(this.display, this.solr.core, this.solr.host).subscribe({
|
||||
DatasetService.searchTerm(this.display).subscribe({
|
||||
DatasetService.searchTerm(this.display, this.openSearch.core, this.openSearch.host).subscribe({
|
||||
// next: (res: Dataset[]) => this.dataHandler(res),
|
||||
next: (res: { datasets: Dataset[], highlights: HitHighlight[] }) => this.dataHandler(res.datasets, res.highlights),
|
||||
error: (error: string) => this.errorHandler(error),
|
||||
|
|
|
@ -149,7 +149,7 @@ input {
|
|||
.autocomplete-result-item {
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
/* padding: 7px 10px; */
|
||||
padding: 0px 0px 0px 5px; // top,right,bottom,left
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,130 +16,6 @@ class DatasetService {
|
|||
*
|
||||
* @param {string} searchTerm - The search term to query.
|
||||
*/
|
||||
// async fetchDataFromOpenSearch(searchTerm: string): Promise<void> {
|
||||
// // Define the OpenSearch endpoint URL
|
||||
// const url = "http://opensearch.geoinformation.dev/tethys-records/_search";
|
||||
|
||||
// // Set the headers for the POST request
|
||||
// const headers = {
|
||||
// "Content-Type": "application/json",
|
||||
// };
|
||||
|
||||
// // Construct the body of the POST request
|
||||
// const body = {
|
||||
// query: {
|
||||
// bool: {
|
||||
// // The `should` clause specifies that at least one of these conditions must match
|
||||
// should: [
|
||||
// {
|
||||
// // Match the search term in the title field with fuzziness enabled and a boost of 3
|
||||
// match: {
|
||||
// title: {
|
||||
// query: searchTerm,
|
||||
// fuzziness: "AUTO", // Enable fuzzy search
|
||||
// boost: 3 // Boosting the relevance of title matches
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// // Match the search term in the author field with fuzziness enabled and a boost of 2
|
||||
// match: {
|
||||
// author: {
|
||||
// query: searchTerm,
|
||||
// fuzziness: "AUTO", // Enable fuzzy search
|
||||
// boost: 2 // Boosting the relevance of author matches
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// // Match the search term in the subject field with fuzziness enabled and a boost of 1
|
||||
// match: {
|
||||
// subject: {
|
||||
// query: searchTerm,
|
||||
// fuzziness: "AUTO", // Enable fuzzy search
|
||||
// boost: 1 // Boosting the relevance of subject matches
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// // Match the search term in the title field with a wildcard
|
||||
// wildcard: {
|
||||
// title: {
|
||||
// value: `${searchTerm}*`, // Wildcard search for terms starting with searchTerm
|
||||
// boost: 3 // Boosting the relevance of title matches
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// // Match the search term in the author field with a wildcard
|
||||
// wildcard: {
|
||||
// author: {
|
||||
// value: `${searchTerm}*`, // Wildcard search for terms starting with searchTerm
|
||||
// boost: 2 // Boosting the relevance of author matches
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// // Match the search term in the subject field with a wildcard
|
||||
// wildcard: {
|
||||
// subject: {
|
||||
// value: `${searchTerm}*`, // Wildcard search for terms starting with searchTerm
|
||||
// boost: 1 // Boosting the relevance of subject matches
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
// // Ensure that at least one of the `should` clauses must match
|
||||
// minimum_should_match: 1
|
||||
// }
|
||||
// },
|
||||
// // Limit the number of search results to 10
|
||||
// size: 10,
|
||||
// // Start from the first result (pagination)
|
||||
// from: 0,
|
||||
// // Sort the results by the `server_date_published` field in descending order
|
||||
// sort: [
|
||||
// { server_date_published: { order: "desc" } }
|
||||
// ],
|
||||
// // Aggregations to provide facets for the `language` and `subject` fields
|
||||
// aggs: {
|
||||
// language: {
|
||||
// terms: {
|
||||
// field: "language.keyword" // Aggregate by the exact values of the `language` field
|
||||
// }
|
||||
// },
|
||||
// subject: {
|
||||
// terms: {
|
||||
// field: "subjects.keyword", // Aggregate by the exact values of the `subjects` field
|
||||
// size: 10 // Limit the number of aggregation buckets to 10
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// try {
|
||||
// // Send the POST request to the OpenSearch endpoint
|
||||
// const response = await fetch(url, {
|
||||
// method: "POST",
|
||||
// headers: headers,
|
||||
// body: JSON.stringify(body),
|
||||
// });
|
||||
|
||||
// // Check if the response is not successful
|
||||
// if (!response.ok) {
|
||||
// throw new Error(`Failed to fetch data from ${url}, status: ${response.status}`);
|
||||
// }
|
||||
|
||||
// // Parse the response JSON
|
||||
// const data = await response.json();
|
||||
// // Log the data from OpenSearch
|
||||
// console.log("Data from OpenSearch:", data);
|
||||
// console.log("Hits:", data.hits.total.value);
|
||||
// } catch (error) {
|
||||
// // Log any errors that occur during the fetch process
|
||||
// console.error("Error fetching data:", error);
|
||||
// }
|
||||
// }
|
||||
|
||||
/* 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&start=0&sort=server_date_published%20desc&facet=on&json.facet.language=%7B%20type%3A%20%22
|
||||
|
@ -148,10 +24,19 @@ class DatasetService {
|
|||
*/
|
||||
|
||||
// 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): Observable<{ datasets: Dataset[], highlights: HitHighlight[] }> {
|
||||
public searchTerm(term: string, openCore: string, openHost: string): Observable<{ datasets: Dataset[], highlights: HitHighlight[] }> {
|
||||
// OpenSearch endpoint
|
||||
const host = "https://" + openHost; // When using geoinformation.dev
|
||||
// const host = "http://" + openHost; // When using local OpenSearch dev endpoint
|
||||
const path = "/" + openCore + "/_search";
|
||||
const base = host + path;
|
||||
/**
|
||||
* The match query used for title, author, and subjects fields is case-insensitive by default. The standard analyzer is typically used, which lowercases the terms.
|
||||
* The wildcard query is case-sensitive by default. To make it case-insensitive, it is needed to use a lowercase filter */
|
||||
const lowercaseTerm = term.toLowerCase(); // Lowercase the search term
|
||||
const body = {
|
||||
query: {
|
||||
bool: {
|
||||
|
@ -159,9 +44,9 @@ class DatasetService {
|
|||
{ match: { title: { query: term, fuzziness: "AUTO", boost: 3 } } },
|
||||
{ match: { author: { query: term, fuzziness: "AUTO", boost: 2 } } },
|
||||
{ match: { subjects: { query: term, fuzziness: "AUTO", boost: 1 } } }, // In SOLR is "subject"!
|
||||
{ wildcard: { title: { value: `${term}*`, boost: 3 } } },
|
||||
{ wildcard: { author: { value: `${term}*`, boost: 2 } } },
|
||||
{ wildcard: { subjects: { value: `${term}*`, boost: 1 } } } // In SOLR is "subject"!
|
||||
{ wildcard: { title: { value: `${lowercaseTerm}*`, boost: 3 } } },
|
||||
{ wildcard: { author: { value: `${lowercaseTerm}*`, boost: 2 } } },
|
||||
{ wildcard: { subjects: { value: `${lowercaseTerm}*`, boost: 1 } } } // In SOLR is "subject"!
|
||||
],
|
||||
minimum_should_match: 1
|
||||
}
|
||||
|
@ -190,7 +75,7 @@ class DatasetService {
|
|||
* One of the key properties of this response object is _source, 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.
|
||||
*/
|
||||
return api.post<OpenSearchResponse>(this.openSearchUrl, body).pipe(
|
||||
return api.post<OpenSearchResponse>(base, body).pipe(
|
||||
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
|
||||
|
@ -206,9 +91,7 @@ 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[]> {
|
||||
// Calling the test method for
|
||||
// this.fetchDataFromOpenSearch(term);
|
||||
// solr endpoint
|
||||
// SOLR endpoint
|
||||
const host = "https://" + solrHost;
|
||||
const path = "/solr/" + solrCore + "/select?";
|
||||
const base = host + path;
|
||||
|
@ -268,6 +151,12 @@ class DatasetService {
|
|||
solrHost: string,
|
||||
start?: string, // Starting page
|
||||
): Observable<SolrResponse> {
|
||||
// console.log("face:", suggestion);
|
||||
// console.log(activeFilterCategories);
|
||||
// console.log(solrCore);
|
||||
// console.log(solrHost);
|
||||
// console.log(start);
|
||||
|
||||
// Construct Solr query parameters
|
||||
const host = "https://" + solrHost;
|
||||
const path = "/solr/" + solrCore + "/select?";
|
||||
|
|
|
@ -59,6 +59,8 @@ export default class DatasetDetailComponent extends Vue {
|
|||
}
|
||||
|
||||
onSearch(suggestion: Suggestion | string): void {
|
||||
console.log("onSearch");
|
||||
|
||||
const host = window.location.host;
|
||||
const parts = host.split(".");
|
||||
if (parts[0] === "doi") {
|
||||
|
|
|
@ -122,11 +122,15 @@ export default class SearchViewComponent extends Vue {
|
|||
|
||||
// Method to trigger a search
|
||||
onSearch(suggestion: Suggestion | string): void {
|
||||
console.log("ONSEARCH");
|
||||
|
||||
// Reset active filter categories and facet results
|
||||
this.activeFilterCategories = new ActiveFilterCategories();
|
||||
this.facets = new FacetResults();
|
||||
|
||||
this.searchTerm = suggestion;
|
||||
console.log("This.searchterm: ", this.searchTerm);
|
||||
|
||||
/* Perform faceted search. The method returns an Observable, and the code subscribes to this Observable to handle the response. If the response is successful, it calls the dataHandler method
|
||||
with the Solr response as a parameter. If there is an error, it calls the errorHandler method with the error message as a parameter */
|
||||
DatasetService.facetedSearch(suggestion, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({
|
||||
|
|
Loading…
Reference in New Issue
Block a user