Browse Source

Merge pull request #7 from zilliztech/uxd-637

[UXD-637] add index api
ryjiang 4 years ago
parent
commit
f2a22eca42

+ 2 - 0
server/src/app.module.ts

@@ -11,6 +11,7 @@ import { AuthModule } from './auth/auth.module';
 import { ServeStaticModule } from '@nestjs/serve-static';
 import { ServeStaticModule } from '@nestjs/serve-static';
 import { join } from 'path';
 import { join } from 'path';
 import { PartitionsModule } from './partitions/partitions.module';
 import { PartitionsModule } from './partitions/partitions.module';
+import { SchemaModule } from './schema/schema.module';
 
 
 @Module({
 @Module({
   imports: [
   imports: [
@@ -23,6 +24,7 @@ import { PartitionsModule } from './partitions/partitions.module';
     UsersModule,
     UsersModule,
     AuthModule,
     AuthModule,
     PartitionsModule,
     PartitionsModule,
+    SchemaModule,
   ],
   ],
   controllers: [AppController],
   controllers: [AppController],
   providers: [
   providers: [

+ 1 - 2
server/src/collections/collections.service.ts

@@ -8,7 +8,7 @@ import {
   GetIndexStateReq,
   GetIndexStateReq,
   LoadCollectionReq,
   LoadCollectionReq,
   ReleaseLoadCollectionReq,
   ReleaseLoadCollectionReq,
-} from '@zilliz/milvus-sdk-node-dev/dist/milvus/types'; // todo: need improve like export types in root file.
+} from '@zilliz/milvus-sdk-node-dev/dist/milvus/types';
 import { throwErrorFromSDK } from '../utils/Error';
 import { throwErrorFromSDK } from '../utils/Error';
 import { findKeyValue } from '../utils/Helper';
 import { findKeyValue } from '../utils/Helper';
 import { ROW_COUNT } from '../utils/Const';
 import { ROW_COUNT } from '../utils/Const';
@@ -71,7 +71,6 @@ export class CollectionsService {
    */
    */
   async getIndexStatus(data: GetIndexStateReq) {
   async getIndexStatus(data: GetIndexStateReq) {
     const res = await this.milvusClient.getIndexState(data);
     const res = await this.milvusClient.getIndexState(data);
-    throwErrorFromSDK(res.status);
     return res;
     return res;
   }
   }
 
 

+ 4 - 0
server/src/collections/dto.ts

@@ -7,18 +7,22 @@ import {
   ArrayNotEmpty,
   ArrayNotEmpty,
 } from 'class-validator';
 } from 'class-validator';
 import { FieldType } from '@zilliz/milvus-sdk-node-dev/dist/milvus/types/Collection'; // todo: need improve like export types in root file.
 import { FieldType } from '@zilliz/milvus-sdk-node-dev/dist/milvus/types/Collection'; // todo: need improve like export types in root file.
+import { ApiProperty } from '@nestjs/swagger';
 
 
 export class CreateCollection {
 export class CreateCollection {
+  @ApiProperty()
   @IsString()
   @IsString()
   @IsNotEmpty({
   @IsNotEmpty({
     message: 'collection_name is empty',
     message: 'collection_name is empty',
   })
   })
   readonly collection_name: string;
   readonly collection_name: string;
 
 
+  @ApiProperty()
   @IsBoolean()
   @IsBoolean()
   @IsOptional()
   @IsOptional()
   readonly autoID: boolean;
   readonly autoID: boolean;
 
 
+  @ApiProperty()
   @IsArray()
   @IsArray()
   @ArrayNotEmpty()
   @ArrayNotEmpty()
   @IsNotEmpty({
   @IsNotEmpty({

+ 3 - 0
server/src/milvus/dto.ts

@@ -1,6 +1,8 @@
+import { ApiProperty } from '@nestjs/swagger';
 import { IsNotEmpty, IsString } from 'class-validator';
 import { IsNotEmpty, IsString } from 'class-validator';
 
 
 export class ConnectMilvus {
 export class ConnectMilvus {
+  @ApiProperty()
   @IsString()
   @IsString()
   @IsNotEmpty({
   @IsNotEmpty({
     message: 'address is empty',
     message: 'address is empty',
@@ -9,6 +11,7 @@ export class ConnectMilvus {
 }
 }
 
 
 export class CheckMilvus {
 export class CheckMilvus {
+  @ApiProperty()
   @IsString()
   @IsString()
   @IsNotEmpty({
   @IsNotEmpty({
     message: 'address is empty',
     message: 'address is empty',

+ 1 - 0
server/src/milvus/milvus.service.ts

@@ -28,6 +28,7 @@ export class MilvusService {
       });
       });
       return { address: this.milvusAddress };
       return { address: this.milvusAddress };
     } catch (error) {
     } catch (error) {
+      console.log(error);
       throw new Error('Connect milvus failed, check your milvus address.');
       throw new Error('Connect milvus failed, check your milvus address.');
     }
     }
   }
   }

+ 7 - 0
server/src/partitions/dto.ts

@@ -1,3 +1,4 @@
+import { ApiProperty } from '@nestjs/swagger';
 import {
 import {
   IsNotEmpty,
   IsNotEmpty,
   IsString,
   IsString,
@@ -11,6 +12,7 @@ export enum ManageType {
   CREATE = 'create',
   CREATE = 'create',
 }
 }
 export class GetPartitionsInfo {
 export class GetPartitionsInfo {
+  @ApiProperty()
   @IsString()
   @IsString()
   @IsNotEmpty({
   @IsNotEmpty({
     message: 'collection_name is empty',
     message: 'collection_name is empty',
@@ -19,29 +21,34 @@ export class GetPartitionsInfo {
 }
 }
 
 
 export class ManagePartition {
 export class ManagePartition {
+  @ApiProperty()
   @IsString()
   @IsString()
   @IsNotEmpty({
   @IsNotEmpty({
     message: 'collection_name is empty',
     message: 'collection_name is empty',
   })
   })
   readonly collection_name: string;
   readonly collection_name: string;
 
 
+  @ApiProperty()
   @IsString()
   @IsString()
   @IsNotEmpty({
   @IsNotEmpty({
     message: 'partition_name is empty',
     message: 'partition_name is empty',
   })
   })
   readonly partition_name: string;
   readonly partition_name: string;
 
 
+  @ApiProperty({ enum: ManageType })
   @IsEnum(ManageType, { message: 'Type allow delete and create' })
   @IsEnum(ManageType, { message: 'Type allow delete and create' })
   readonly type: ManageType;
   readonly type: ManageType;
 }
 }
 
 
 export class LoadPartitions {
 export class LoadPartitions {
+  @ApiProperty()
   @IsString()
   @IsString()
   @IsNotEmpty({
   @IsNotEmpty({
     message: 'collection_name is empty',
     message: 'collection_name is empty',
   })
   })
   readonly collection_name: string;
   readonly collection_name: string;
 
 
+  @ApiProperty()
   @IsArray()
   @IsArray()
   @ArrayNotEmpty()
   @ArrayNotEmpty()
   @IsNotEmpty({
   @IsNotEmpty({

+ 96 - 0
server/src/schema/dto.ts

@@ -0,0 +1,96 @@
+import { ApiProperty } from '@nestjs/swagger';
+import {
+  IsNotEmpty,
+  IsString,
+  IsArray,
+  IsEnum,
+  IsOptional,
+} from 'class-validator';
+
+class KeyValuePair {
+  @ApiProperty()
+  key: string;
+  @ApiProperty()
+  value: string;
+}
+
+export enum ManageType {
+  DELETE = 'delete',
+  CREATE = 'create',
+}
+
+export class ManageIndex {
+  @ApiProperty({ enum: ManageType })
+  @IsEnum(ManageType, { message: 'Type allow delete and create' })
+  readonly type: ManageType;
+
+  @ApiProperty()
+  @IsString()
+  @IsNotEmpty({
+    message: 'collection_name is empty',
+  })
+  readonly collection_name: string;
+
+  @ApiProperty()
+  @IsString()
+  @IsNotEmpty({
+    message: 'field_name is empty',
+  })
+  readonly field_name: string;
+
+  @ApiProperty({
+    type: [KeyValuePair],
+  })
+  @IsArray()
+  @IsOptional()
+  readonly extra_params?: KeyValuePair[];
+}
+
+export class DescribeIndex {
+  @ApiProperty()
+  @IsString()
+  @IsNotEmpty({
+    message: 'collection_name is empty',
+  })
+  readonly collection_name: string;
+
+  @ApiProperty()
+  @IsString()
+  @IsOptional()
+  readonly field_name?: string;
+}
+
+export class GetIndexState {
+  @ApiProperty()
+  @IsString()
+  @IsNotEmpty({
+    message: 'collection_name is empty',
+  })
+  readonly collection_name: string;
+
+  @ApiProperty()
+  @IsString()
+  @IsOptional()
+  readonly field_name?: string;
+}
+
+export class GetIndexProgress {
+  @ApiProperty()
+  @IsString()
+  @IsNotEmpty({
+    message: 'collection_name is empty',
+  })
+  readonly collection_name: string;
+
+  @ApiProperty()
+  @IsString()
+  @IsNotEmpty({
+    message: 'index_name is empty',
+  })
+  readonly index_name: string;
+
+  @ApiProperty()
+  @IsString()
+  @IsOptional()
+  readonly field_name?: string;
+}

+ 18 - 0
server/src/schema/schema.controller.spec.ts

@@ -0,0 +1,18 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { SchemaController } from './schema.controller';
+
+describe('SchemaController', () => {
+  let controller: SchemaController;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      controllers: [SchemaController],
+    }).compile();
+
+    controller = module.get<SchemaController>(SchemaController);
+  });
+
+  it('should be defined', () => {
+    expect(controller).toBeDefined();
+  });
+});

+ 53 - 0
server/src/schema/schema.controller.ts

@@ -0,0 +1,53 @@
+import {
+  Body,
+  Controller,
+  Get,
+  Post,
+  Query,
+  UsePipes,
+  ValidationPipe,
+} from '@nestjs/common';
+import {
+  DescribeIndex,
+  GetIndexProgress,
+  ManageIndex,
+  ManageType,
+  GetIndexState,
+} from './dto';
+import { SchemaService } from './schema.service';
+
+@Controller('schema')
+export class SchemaController {
+  constructor(private schemaService: SchemaService) {}
+
+  @Post('index')
+  @UsePipes(new ValidationPipe())
+  async manageIndex(@Body() body: ManageIndex) {
+    const { type, collection_name, extra_params, field_name } = body;
+    return type === ManageType.CREATE
+      ? await this.schemaService.createIndex({
+          collection_name,
+          extra_params,
+          field_name,
+        })
+      : await this.schemaService.dropIndex({ collection_name, field_name });
+  }
+
+  @Get('index')
+  @UsePipes(new ValidationPipe())
+  async describeIndex(@Query() query: DescribeIndex) {
+    return await this.schemaService.describeIndex(query);
+  }
+
+  @Get('index/progress')
+  @UsePipes(new ValidationPipe())
+  async getIndexProgress(@Query() query: GetIndexProgress) {
+    return await this.schemaService.getIndexBuildProgress(query);
+  }
+
+  @Get('index/state')
+  @UsePipes(new ValidationPipe())
+  async getIndexState(@Query() query: GetIndexState) {
+    return await this.schemaService.getIndexState(query);
+  }
+}

+ 11 - 0
server/src/schema/schema.module.ts

@@ -0,0 +1,11 @@
+import { Module } from '@nestjs/common';
+import { MilvusModule } from '../milvus/milvus.module';
+import { SchemaController } from './schema.controller';
+import { SchemaService } from './schema.service';
+
+@Module({
+  imports: [MilvusModule],
+  controllers: [SchemaController],
+  providers: [SchemaService],
+})
+export class SchemaModule {}

+ 18 - 0
server/src/schema/schema.service.spec.ts

@@ -0,0 +1,18 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { SchemaService } from './schema.service';
+
+describe('SchemaService', () => {
+  let service: SchemaService;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      providers: [SchemaService],
+    }).compile();
+
+    service = module.get<SchemaService>(SchemaService);
+  });
+
+  it('should be defined', () => {
+    expect(service).toBeDefined();
+  });
+});

+ 49 - 0
server/src/schema/schema.service.ts

@@ -0,0 +1,49 @@
+import { Injectable } from '@nestjs/common';
+import {
+  CreateIndexReq,
+  DescribeIndexReq,
+  DropIndexReq,
+  GetIndexBuildProgressReq,
+  GetIndexStateReq,
+} from '@zilliz/milvus-sdk-node-dev/dist/milvus/types';
+import { throwErrorFromSDK } from 'src/utils/Error';
+import { MilvusService } from '../milvus/milvus.service';
+
+@Injectable()
+export class SchemaService {
+  constructor(private milvusService: MilvusService) {}
+
+  get milvusClient() {
+    return this.milvusService.milvusClientGetter;
+  }
+
+  async createIndex(data: CreateIndexReq) {
+    const res = await this.milvusClient.createIndex(data);
+    throwErrorFromSDK(res);
+    return res;
+  }
+
+  async describeIndex(data: DescribeIndexReq) {
+    const res = await this.milvusClient.describeIndex(data);
+    throwErrorFromSDK(res.status);
+    return res;
+  }
+
+  async dropIndex(data: DropIndexReq) {
+    const res = await this.milvusClient.dropIndex(data);
+    throwErrorFromSDK(res);
+    return res;
+  }
+
+  async getIndexState(data: GetIndexStateReq) {
+    const res = await this.milvusClient.getIndexState(data);
+    throwErrorFromSDK(res.status);
+    return res;
+  }
+
+  async getIndexBuildProgress(data: GetIndexBuildProgressReq) {
+    const res = await this.milvusClient.getIndexBuildProgress(data);
+    throwErrorFromSDK(res.status);
+    return res;
+  }
+}