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 findByContext | ||||||||
findByContext(query: SearchQueryDto)
|
||||||||
Finds relevant documents by context using the given query string
Parameters :
Returns :
Promise<EsResponseDto>
Elasticsearch response |
Async findByID | ||||||||
findByID(uuid: string)
|
||||||||
Finds a paper by its own ID
Parameters :
Returns :
Promise<EsResponseDto>
Elasticsearch hits or an error object |
Private Readonly ES_IP |
Default value : process.env.ES_CONTAINER_NAME
|
Elasticsearch IP address |
Private Readonly ES_PORT |
Default value : process.env.ES_PORT
|
Elastichsearch server port-number |
import { HttpService } from "@nestjs/axios";
import { GatewayTimeoutException, ImATeapotException, Injectable, NotFoundException } from "@nestjs/common";
import { map, take } from "rxjs";
import { EsMultimatchQueryDto } from "src/core/domain/dtos/elastic/es-multimatch.dto";
import { EsResponseDto, SearchQueryDto} from "../../domain/dtos";
import { EsQueryDto } from "../../domain/dtos/elastic/es-query.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;
/**
* Elasticsearch IP address
*/
private readonly ES_IP = process.env.ES_CONTAINER_NAME;
/**
* Finds a paper by its own ID
* @param uuid String, that represents unique identifier of a paper
* @returns Elasticsearch hits or an error object
*/
async findByID(uuid: string): Promise<EsResponseDto> { // Should I change 'object' to specific DTO?
const es_query: EsQueryDto = new EsQueryDto();
es_query.size = 1;
es_query.query = {
query_string: {
query: ('id:' + uuid),
}
}
return new Promise((resolve, reject) => {
try {
(this.httpService.get<EsResponseDto>(`http://${this.ES_IP}:${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 GatewayTimeoutException('Elasticsearch Timed Out'));
}
if (!res?.hits?.hits?.length) {
reject(new NotFoundException);
}
resolve(res);
});
} catch (error) {
reject(error);
}
});
}
/**
* Finds relevant documents by context using the given query string
* @param query, <EsQueryDto>
* @returns Elasticsearch response
*/
async findByContext(query: SearchQueryDto): Promise<EsResponseDto> {
// Contruct a body for querying Elasticsearch
const es_query: EsMultimatchQueryDto = new EsMultimatchQueryDto(query.query, [
'title', 'content'
]);
es_query.from = query.offset;
es_query.size = query.limit;
return new Promise((resolve, reject) => {
try {
(this.httpService.get<EsResponseDto>(`http://${this.ES_IP}:${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 GatewayTimeoutException('Elasticsearch Timed Out'));
}
resolve(res);
});
} catch (error) {
reject(error);
}
});
}
}