Sfoglia il codice sorgente

feat(server): Add groupByProducts option to SearchInput

Michael Bromley 7 anni fa
parent
commit
bfee4b2693

File diff suppressed because it is too large
+ 0 - 0
schema.json


+ 5 - 4
server/src/api/types/search.api.graphql

@@ -9,6 +9,7 @@ type Mutation {
 input SearchInput {
     term: String
     facetIds: [String!]
+    groupByProduct: Boolean
     take: Int
     skip: Int
 }
@@ -21,13 +22,13 @@ type SearchResponse {
 
 type SearchResult {
     sku: String!
-    productVariantName: String!
-    productName: String!
-    productVariantId: ID!
     productId: ID!
-    description: String!
+    productName: String!
     productPreview: String!
+    productVariantId: ID!
+    productVariantName: String!
     productVariantPreview: String!
+    description: String!
     facetIds: [String!]!
     facetValueIds: [String!]!
     score: Float!

+ 3 - 0
server/src/plugin/default-asset-server/default-asset-storage-strategy.ts

@@ -48,6 +48,9 @@ export class DefaultAssetStorageStrategy implements AssetStorageStrategy {
     }
 
     toAbsoluteUrl(request: Request, identifier: string): string {
+        if (!identifier) {
+            return '';
+        }
         return `${request.protocol}://${request.get('host')}/${this.route}/${identifier}`;
     }
 

+ 13 - 3
server/src/plugin/default-search-engine/fulltext-search.service.ts

@@ -1,6 +1,6 @@
 import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
-import { Connection, SelectQueryBuilder } from 'typeorm';
+import { Brackets, Connection, Like, SelectQueryBuilder } from 'typeorm';
 
 import { LanguageCode, SearchInput, SearchResponse } from '../../../../shared/generated-types';
 import { Omit } from '../../../../shared/omit';
@@ -149,6 +149,7 @@ export class FulltextSearchService {
         input: SearchInput,
     ): SelectQueryBuilder<SearchIndexItem> {
         const { term, facetIds } = input;
+        qb.where('true');
         if (term && term.length > this.minTermLength) {
             qb.addSelect(`IF (sku LIKE :like_term, 10, 0)`, 'sku_score')
                 .addSelect(
@@ -159,16 +160,25 @@ export class FulltextSearchService {
                         MATCH (description) AGAINST (:term)* 1`,
                     'score',
                 )
-                .having(`score > 0`)
+                .andWhere(
+                    new Brackets(qb1 => {
+                        qb1.where('sku LIKE :like_term')
+                            .orWhere('MATCH (productName) AGAINST (:term)')
+                            .orWhere('MATCH (productVariantName) AGAINST (:term)')
+                            .orWhere('MATCH (description) AGAINST (:term)');
+                    }),
+                )
                 .setParameters({ term, like_term: `%${term}%` });
         }
         if (facetIds) {
-            qb.where('true');
             for (const id of facetIds) {
                 const placeholder = '_' + id;
                 qb.andWhere(`FIND_IN_SET(:${placeholder}, facetValueIds)`, { [placeholder]: id });
             }
         }
+        if (input.groupByProduct === true) {
+            qb.groupBy('productId');
+        }
         return qb;
     }
 

+ 1 - 0
shared/generated-types.ts

@@ -981,6 +981,7 @@ export interface RoleFilterParameter {
 export interface SearchInput {
     term?: string | null;
     facetIds?: string[] | null;
+    groupByProduct?: boolean | null;
     take?: number | null;
     skip?: number | null;
 }

Some files were not shown because too many files changed in this diff