From f5ad2e0ff79fbf003e2363cfcd8630a1f9693a3c Mon Sep 17 00:00:00 2001 From: Danny Mikhaylov Date: Tue, 8 Nov 2022 05:18:17 +0300 Subject: [PATCH] Changed 'match' query to 'multi-match'. Allows to search for both 'content' and 'title' of the paper --- .../domain/dtos/elastic/es-multimatch.dto.ts | 68 +++++++++++++++++++ src/core/services/common/search.service.ts | 11 ++- 2 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 src/core/domain/dtos/elastic/es-multimatch.dto.ts diff --git a/src/core/domain/dtos/elastic/es-multimatch.dto.ts b/src/core/domain/dtos/elastic/es-multimatch.dto.ts new file mode 100644 index 0000000..6617fea --- /dev/null +++ b/src/core/domain/dtos/elastic/es-multimatch.dto.ts @@ -0,0 +1,68 @@ +import { ApiExtraModels, ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; +import { IsArray, IsDefined, IsInt, IsObject, IsOptional } from "class-validator"; +import { EsPit } from "../../interfaces/elastic/es-pit.interface"; +import { EsQuery } from "../../interfaces/elastic/es-query.interface" + +/** + * List of allowed properties in this DTO + */ + const allowedProperties = ['query']; + + /** + * Elasticsearch multi-match query DTO + */ + @ApiExtraModels() + export class EsMultimatchQueryDto { + /** + * Offset from the start of the list of hits + */ + @IsOptional() + @IsInt() + @ApiPropertyOptional({ + description: 'Offset from the start of the list of hits', + example: 5, + }) + public from?: number; + + /** + * Maximum number of elements returned by Elasticsearch + */ + @IsOptional() + @IsInt() + @ApiPropertyOptional({ + description: 'Maximum number of elements returned by Elasticsearch', + example: 30 + }) + public size?: number; + + /** + * The search query object passed to Elasticsearch + */ + @IsDefined() + @IsObject() + @ApiProperty({ + description: 'Search query object passed to Elasticsearch', + example: { + multi_match: { + query: 'Maths', + fields: [ + 'title', + 'content' + ] + } + }, + }) + private readonly query: Object; + + /** + * Constructs a multi-match + */ + constructor(query: string = '', fields: Array = ['content']) { + this.query = { + multi_match: { + query: query, + fields: fields + } + } + } + } \ No newline at end of file diff --git a/src/core/services/common/search.service.ts b/src/core/services/common/search.service.ts index b037ab5..7e5a47c 100644 --- a/src/core/services/common/search.service.ts +++ b/src/core/services/common/search.service.ts @@ -1,6 +1,7 @@ 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"; @@ -69,13 +70,9 @@ export class SearchService { */ async findByContext(query: SearchQueryDto): Promise { // Contruct a body for querying Elasticsearch - const es_query: EsQueryDto = new EsQueryDto(); - es_query.query = { - query_string: { - query: query.query, - default_field: 'content', - } - }; + const es_query: EsMultimatchQueryDto = new EsMultimatchQueryDto(query.query, [ + 'title', 'content' + ]); es_query.from = query.offset; es_query.size = query.limit;