src/core/services/common/search.service.ts
Search service provider
Properties |
|
Methods |
|
constructor(httpService: HttpService)
|
||||||
Constructs the service with injection of HTTPService instance
Parameters :
|
Async deletePIT | ||||||||
deletePIT(pitID: string)
|
||||||||
Deletes the PIT specified by provided ID
Parameters :
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 :
Returns :
Promise<SearchResultDto>
Elasticsearch hits or an error object |
Async findByID | ||||||
findByID(uuid: string)
|
||||||
Finds a paper by its own ID
Parameters :
Returns :
Promise<SearchResultDto>
Elasticsearch hits or an error object |
Async getPIT | ||||||||||
getPIT(alive: number)
|
||||||||||
Acquires a PIT ID from Elasticsearch, needed for a request
Parameters :
Returns :
Promise<string>
Point-In-Time ID |
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);
}
})
}
}