OpenSearch - some progress in migration

This commit is contained in:
Porras-Bernardez 2024-06-06 17:11:54 +02:00
parent a853e93b68
commit 6d1c1b28c3
5 changed files with 143 additions and 137 deletions

View file

@ -3,44 +3,12 @@ import api from "../api/api";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
import { Dataset, DbDataset, Suggestion } from "@/models/dataset";
import { SolrResponse } from "@/models/headers";
import { OpenSearchResponse, SolrResponse } from "@/models/headers";
import { ActiveFilterCategories } from "@/models/solr";
import { VUE_API } from "@/constants";
import { deserialize } from "class-transformer";
class DatasetService {
// /* Initial test method to fetch and log data from the local OpenSearch endpoint (new backend) */
// async fetchDataFromOpenSearch(searchTerm: string): Promise<void> {
// const url = "http://192.168.21.18/tethys-records/_search";
// const headers = {
// "Content-Type": "application/json",
// };
// const body = {
// query: {
// match: {
// title: searchTerm,
// },
// },
// };
// try {
// const response = await fetch(url, {
// method: "POST",
// headers: headers,
// body: JSON.stringify(body),
// });
// if (!response.ok) {
// throw new Error(`Failed to fetch data from ${url}, status: ${response.status}`);
// }
// const data = await response.json();
// console.log("Data from OpenSearch:", data);
// } catch (error) {
// console.error("Error fetching data:", error);
// }
// }
/**
* Fetch data from the OpenSearch endpoint with fuzzy search enabled.
* This function allows for misspellings in the search term and boosts
@ -50,7 +18,7 @@ class DatasetService {
*/
async fetchDataFromOpenSearch(searchTerm: string): Promise<void> {
// Define the OpenSearch endpoint URL
const url = "http://192.168.21.18/tethys-records/_search";
const url = "http://opensearch.geoinformation.dev/tethys-records/_search";
// Set the headers for the POST request
const headers = {
@ -149,68 +117,6 @@ class DatasetService {
}
};
// // 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 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, {
@ -241,10 +147,41 @@ class DatasetService {
terms%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
*/
private openSearchUrl = "http://opensearch.geoinformation.dev/tethys-records/_search";
public searchTerm(term: string): Observable<Dataset[]> {
const body = {
query: {
bool: {
should: [
{ match: { title: { query: term, fuzziness: "AUTO", boost: 3 } } },
{ match: { author: { query: term, fuzziness: "AUTO", boost: 2 } } },
{ match: { subject: { query: term, fuzziness: "AUTO", boost: 1 } } },
{ wildcard: { title: { value: `${term}*`, boost: 3 } } },
{ wildcard: { author: { value: `${term}*`, boost: 2 } } },
{ wildcard: { subject: { value: `${term}*`, boost: 1 } } }
],
minimum_should_match: 1
}
},
size: 10,
from: 0,
sort: [{ server_date_published: { order: "desc" } }],
aggs: {
language: { terms: { field: "language.keyword" } },
subject: { terms: { field: "subjects.keyword", size: 10 } }
}
};
return api.post<OpenSearchResponse>(this.openSearchUrl, body).pipe(
map(response => response.hits.hits.map(hit => hit._source))
);
}
// For the autocomplete search. Method to perform a search based on a term
public searchTerm(term: string, solrCore: string, solrHost: string): Observable<Dataset[]> {
public searchTerm_SOLR(term: string, solrCore: string, solrHost: string): Observable<Dataset[]> {
// Calling the test method for
this.fetchDataFromOpenSearch(term);
// this.fetchDataFromOpenSearch(term);
// solr endpoint
const host = "https://" + solrHost;
const path = "/solr/" + solrCore + "/select?";
@ -276,6 +213,11 @@ class DatasetService {
};
// 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;
@ -290,7 +232,9 @@ class DatasetService {
&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 */
// Method to perform a faceted search
/**
* 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(
suggestion: Suggestion | string,
activeFilterCategories: ActiveFilterCategories,
@ -316,13 +260,13 @@ class DatasetService {
"doctype",
].toString();
// Determine search term, query operator, and query fields based on the suggestion type
// 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;
if (typeof suggestion === "string") {
if (typeof suggestion === "string") { // f suggestion is a string, it appends a wildcard (*) for partial matches.
term = suggestion + "*";
queryOperator = "or";
qfFields = "title^3 author^2 subject^1";
} else if (suggestion instanceof 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 + '"';
queryOperator = "and";
qfFields = undefined;