File

src/core/services/common/search.service.ts

Description

Search service provider

Index

Properties
Methods

Constructor

constructor(httpService: HttpService)

Constructs the service with injection of HTTPService instance

Parameters :
Name Type Optional
httpService HttpService No

Methods

Async deletePIT
deletePIT(pitID: string)

Deletes the PIT specified by provided ID

Parameters :
Name Type Optional Description
pitID string No

, ID of the PIT, that would be deleted

Returns : Promise<boolean>

true/false, depending on the result of deletion of the PIT

Async findByContext
findByContext(query_str: string)

Finds relevant documents by context using the given query string

Parameters :
Name Type Optional
query_str string No

Elasticsearch hits or an error object

Async findByID
findByID(uuid: string)

Finds a paper by its own ID

Parameters :
Name Type Optional
uuid string No

Elasticsearch hits or an error object

Async getPIT
getPIT(alive: number)

Acquires a PIT ID from Elasticsearch, needed for a request

Parameters :
Name Type Optional Default value Description
alive number No 1

, amount of time in minutes (defaults to 1)

Returns : Promise<string>

Point-In-Time ID

Properties

Private Readonly ES_PORT
Default value : process.env.ES_PORT

Elastichsearch server port-number

import { HttpService } from "@nestjs/axios";
import { Injectable } from "@nestjs/common";
import { map, take } from "rxjs";
import { EsResponseDto } from "src/core/domain/dtos";
import { SearchResultDto } from "src/core/domain/dtos/search-result.dto";

/**
 * Search service provider
 */
@Injectable()
export class SearchService {
    /**
     * Constructs the service with injection of
     * HTTPService instance
     * @param httpService 
     */
    constructor(private readonly httpService: HttpService) {}

    /**
     * Elastichsearch server port-number
     */
    private readonly ES_PORT = process.env.ES_PORT;
    
    /**
     * Finds a paper by its own ID
     * @param uuid 
     * @returns Elasticsearch hits or an error object
     */
    async findByID(uuid: string): Promise<SearchResultDto> { // Should I change 'object' to specific DTO?
        let es_query = {
            query: {
                query_string: {
                    query: 'id:' + uuid
                }
            },
        }

        return new Promise((resolve, reject) => {
            try {
                (this.httpService.get<EsResponseDto>(`http://localhost:${this.ES_PORT}/_search`, {
                    data: es_query,
                    headers: {'Content-Type': 'application/json'},
                }))
                .pipe(take(1), map(axiosRes => axiosRes.data))
                .subscribe((res: EsResponseDto) => {
                    if (res.timed_out) {
                        reject(new SearchResultDto(504, {message: 'Timed Out'}));
                    }

                    resolve(new SearchResultDto(200, res.hits));
                });
            } catch (error) {
                reject(new SearchResultDto(700, error));
            }
        });
    }

    /**
     * Finds relevant documents by context using the given query string
     * @param query_str 
     * @returns Elasticsearch hits or an error object
     */
    async findByContext(query_str: string): Promise<SearchResultDto> {
        let es_query = {
            query: {
                query_string: {
                    query: query_str,
                    default_field: "content"
                }
            },
        }

        let pitID = this.getPIT(1);

        return new Promise((resolve, reject) => {
            try {
                (this.httpService.get<EsResponseDto>(`http://localhost:${this.ES_PORT}/_search`, {
                    data: es_query,
                    headers: {'Content-Type': 'application/json'},
                }))
                .pipe(take(1), map(axiosRes => axiosRes.data))
                .subscribe((res: EsResponseDto) => {
                    if (res.timed_out) {
                        reject(new SearchResultDto(504, {status: 504, message: 'Timed Out'}));
                    }            
                    
                    resolve(new SearchResultDto(200, res.hits));
                });
            } catch (error) {
                reject(new SearchResultDto(700, error));
            }
        });
    }

    /**
     * Acquires a PIT ID from Elasticsearch, needed for a request
     * @param alive, amount of time in minutes (defaults to 1)
     * @returns Point-In-Time ID
     */
    async getPIT(alive: number = 1): Promise<string> {
        return new Promise((resolve, reject) => {
            try {
                (this.httpService.post(`http://localhost:${this.ES_PORT}/papers/_pit?keep_alive=${alive}m`)
                    .pipe(take(1), map(axiosRes => axiosRes.data))
                    .subscribe((res) => {
                        resolve(res.id);
                    }));
            } catch (error) {
                reject(error);
            }
        });
    }

    /**
     * Deletes the PIT specified by provided ID
     * @param pitID, ID of the PIT, that would be deleted
     * @returns true/false, depending on the result of deletion of the PIT
     */
    async deletePIT(pitID: string): Promise<boolean> {
        return new Promise((resolve, reject) => {
            try {
                this.httpService.delete(`http://localhost:${this.ES_PORT}/papers/_pit`, {
                    data: { id: pitID },
                    headers: { 'Content-Type': 'application/json' },
                })
                .pipe(take(1), map(axiosRes => axiosRes.data))
                .subscribe((res) => {
                    resolve(res.succeeded);
                });
            } catch (error) {
                reject(error);
            }
        })
    }
}

results matching ""

    No results matching ""