123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 |
- import { NextFunction, Request, Response, Router } from 'express';
- import { dtoValidationMiddleware } from '../middleware/validation';
- import { CollectionsService } from './collections.service';
- import {
- LoadCollectionReq,
- IndexType,
- MetricType,
- } from '@zilliz/milvus2-sdk-node';
- import {
- CreateAliasDto,
- CreateCollectionDto,
- InsertDataDto,
- ImportSampleDto,
- QueryDto,
- RenameCollectionDto,
- DuplicateCollectionDto,
- ManageIndexDto,
- } from './dto';
- export class CollectionController {
- private collectionsService: CollectionsService;
- private router: Router;
- constructor() {
- this.collectionsService = new CollectionsService();
- this.router = Router();
- }
- get collectionsServiceGetter() {
- return this.collectionsService;
- }
- generateRoutes() {
- // get all collections
- this.router.get('/', this.showCollections.bind(this));
- this.router.get('/names', this.getCollectionNames.bind(this));
- // get all collections statistics
- this.router.get('/statistics', this.getStatistics.bind(this));
- // index
- this.router.post(
- '/index',
- dtoValidationMiddleware(ManageIndexDto),
- this.manageIndex.bind(this)
- );
- this.router.get('/index', this.describeIndex.bind(this));
- // get collection with index info
- this.router.get('/:name', this.describeCollection.bind(this));
- this.router.get(
- '/:name/unformatted',
- this.describeUnformattedCollection.bind(this)
- );
- // get count
- this.router.get('/:name/count', this.count.bind(this));
- // create collection
- this.router.post(
- '/',
- dtoValidationMiddleware(CreateCollectionDto),
- this.createCollection.bind(this)
- );
- // drop collection
- this.router.delete('/:name', this.dropCollection.bind(this));
- // rename collection
- this.router.post(
- '/:name',
- dtoValidationMiddleware(RenameCollectionDto),
- this.renameCollection.bind(this)
- );
- // duplicate collection
- this.router.post(
- '/:name/duplicate',
- dtoValidationMiddleware(DuplicateCollectionDto),
- this.duplicateCollection.bind(this)
- );
- // get collection statistics
- this.router.get(
- '/:name/statistics',
- this.getCollectionStatistics.bind(this)
- );
- // load / release
- this.router.put('/:name/load', this.loadCollection.bind(this));
- this.router.put('/:name/release', this.releaseCollection.bind(this));
- this.router.put('/:name/empty', this.empty.bind(this));
- // alter collection
- this.router.put(
- '/:name/properties',
- this.setCollectionProperties.bind(this)
- );
- // insert data
- this.router.post(
- '/:name/insert',
- dtoValidationMiddleware(InsertDataDto),
- this.insert.bind(this)
- );
- this.router.post(
- '/:name/upsert',
- dtoValidationMiddleware(InsertDataDto),
- this.upsert.bind(this)
- );
- // insert sample data
- this.router.post(
- '/:name/importSample',
- dtoValidationMiddleware(ImportSampleDto),
- this.importSample.bind(this)
- );
- // we need use req.body, so we can't use delete here
- this.router.put('/:name/entities', this.deleteEntities.bind(this));
- this.router.post('/:name/search', this.vectorSearch.bind(this));
- // query
- this.router.post(
- '/:name/query',
- dtoValidationMiddleware(QueryDto),
- this.query.bind(this)
- );
- // create alias
- this.router.post(
- '/:name/alias',
- dtoValidationMiddleware(CreateAliasDto),
- this.createAlias.bind(this)
- );
- // drop alias
- this.router.delete('/:name/alias/:alias', this.dropAlias.bind(this));
- // segments
- this.router.get('/:name/psegments', this.getPSegment.bind(this));
- this.router.get('/:name/qsegments', this.getQSegment.bind(this));
- // compact
- this.router.put('/:name/compact', this.compact.bind(this));
- return this.router;
- }
- async showCollections(req: Request, res: Response, next: NextFunction) {
- const type = parseInt('' + req.query?.type, 10);
- try {
- const result =
- type === 1
- ? await this.collectionsService.getLoadedCollections(
- req.clientId,
- req.db_name
- )
- : await this.collectionsService.getAllCollections(
- req.clientId,
- [],
- req.db_name
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async getCollectionNames(req: Request, res: Response, next: NextFunction) {
- try {
- const db_name = req.query?.db_name;
- const request = {} as any;
- if (db_name) {
- request.db_name = db_name;
- }
- const result = await this.collectionsService.showCollections(
- req.clientId,
- request
- );
- res.send(
- result.data
- .sort((a, b) => {
- // sort by name
- return a.name.localeCompare(b.name);
- })
- .map((item: any) => item.name)
- );
- } catch (error) {
- next(error);
- }
- }
- async getStatistics(req: Request, res: Response, next: NextFunction) {
- try {
- const result = await this.collectionsService.getStatistics(
- req.clientId,
- req.db_name
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async createCollection(req: Request, res: Response, next: NextFunction) {
- const createCollectionData = req.body;
- if (createCollectionData.loadAfterCreate) {
- // build index_params for all fields
- const fields = createCollectionData.fields;
- const index_params = fields.map((field: any) => {
- const params: any = {
- field_name: field.name,
- index_type: IndexType.AUTOINDEX,
- };
- if (field.is_function_output) {
- params.metric_type = MetricType.BM25;
- }
- return params;
- });
- createCollectionData.index_params = index_params;
- }
- try {
- const result = await this.collectionsService.createCollection(
- req.clientId,
- createCollectionData
- );
- // load collection after create
- if (createCollectionData.loadAfterCreate) {
- await this.collectionsService.loadCollectionAsync(req.clientId, {
- collection_name: createCollectionData.collection_name,
- db_name: req.db_name,
- });
- }
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async renameCollection(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- const data = req.body;
- try {
- const result = await this.collectionsService.renameCollection(
- req.clientId,
- {
- collection_name: name,
- ...data,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async setCollectionProperties(
- req: Request,
- res: Response,
- next: NextFunction
- ) {
- const name = req.params?.name;
- const data = req.body;
- try {
- const result = await this.collectionsService.alterCollection(
- req.clientId,
- {
- collection_name: name,
- ...data,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async duplicateCollection(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- const data = req.body;
- try {
- const result = await this.collectionsService.duplicateCollection(
- req.clientId,
- {
- collection_name: name,
- ...data,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async dropCollection(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.dropCollection(
- req.clientId,
- {
- collection_name: name,
- db_name: req.db_name,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async describeCollection(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.getAllCollections(
- req.clientId,
- [name],
- req.db_name
- );
- res.send(result[0]);
- } catch (error) {
- next(error);
- }
- }
- async describeUnformattedCollection(
- req: Request,
- res: Response,
- next: NextFunction
- ) {
- const name = req.params?.name;
- try {
- const result =
- await this.collectionsService.describeUnformattedCollection(
- req.clientId,
- name,
- req.db_name
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async getCollectionStatistics(
- req: Request,
- res: Response,
- next: NextFunction
- ) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.getCollectionStatistics(
- req.clientId,
- {
- collection_name: name,
- db_name: req.db_name,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async loadCollection(req: Request, res: Response, next: NextFunction) {
- const collection_name = req.params?.name;
- const data = req.body;
- const param: LoadCollectionReq = { collection_name, db_name: req.db_name };
- if (data.replica_number) {
- param.replica_number = Number(data.replica_number);
- }
- try {
- const result = await this.collectionsService.loadCollectionAsync(
- req.clientId,
- param
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async releaseCollection(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.releaseCollection(
- req.clientId,
- {
- collection_name: name,
- db_name: req.db_name,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async insert(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- const data = req.body;
- try {
- const result = await this.collectionsService.insert(req.clientId, {
- collection_name: name,
- ...data,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async upsert(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- const data = req.body;
- try {
- const result = await this.collectionsService.upsert(req.clientId, {
- collection_name: name,
- ...data,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async importSample(req: Request, res: Response, next: NextFunction) {
- const data = req.body;
- try {
- const result = await this.collectionsService.importSample(req.clientId, {
- ...data,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async deleteEntities(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- const data = req.body;
- try {
- const result = await this.collectionsService.deleteEntities(
- req.clientId,
- {
- collection_name: name,
- ...data,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async vectorSearch(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- const data = req.body;
- try {
- const result = await this.collectionsService.vectorSearch(req.clientId, {
- collection_name: name,
- ...data,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async query(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- const data = req.body;
- const resultLimit: any = req.query?.limit;
- const resultPage: any = req.query?.page;
- try {
- const limit = parseInt(resultLimit, 10);
- const page = isNaN(resultPage) ? 0 : parseInt(resultPage, 10);
- const result = await this.collectionsService.query(req.clientId, {
- collection_name: name,
- ...data,
- });
- // const queryResultList = result.data;
- const queryResultLength = result.data.length;
- res.send({ ...result, limit, page, total: queryResultLength });
- } catch (error) {
- next(error);
- }
- }
- async createAlias(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- const data = req.body;
- try {
- const result = await this.collectionsService.createAlias(req.clientId, {
- collection_name: name,
- ...data,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async dropAlias(req: Request, res: Response, next: NextFunction) {
- const alias = req.params?.alias;
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.dropAlias(
- req.clientId,
- name,
- {
- alias,
- db_name: req.db_name,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async getReplicas(req: Request, res: Response, next: NextFunction) {
- const collectionID = req.params?.collectionID;
- try {
- const result = await this.collectionsService.getReplicas(req.clientId, {
- collectionID,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async getPSegment(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.getPersistentSegmentInfo(
- req.clientId,
- {
- collectionName: name,
- dbName: req.db_name,
- }
- );
- res.send(result.infos);
- } catch (error) {
- next(error);
- }
- }
- async getQSegment(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.getQuerySegmentInfo(
- req.clientId,
- {
- collectionName: name,
- dbName: req.db_name,
- }
- );
- res.send(result.infos);
- } catch (error) {
- next(error);
- }
- }
- async compact(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.compact(req.clientId, {
- collection_name: name,
- db_name: req.db_name,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async count(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.count(req.clientId, {
- collection_name: name,
- db_name: req.db_name,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async empty(req: Request, res: Response, next: NextFunction) {
- const name = req.params?.name;
- try {
- const result = await this.collectionsService.emptyCollection(
- req.clientId,
- {
- collection_name: name,
- db_name: req.db_name,
- }
- );
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async manageIndex(req: Request, res: Response, next: NextFunction) {
- const { type, collection_name, index_name, extra_params, field_name } =
- req.body;
- try {
- const result =
- type.toLocaleLowerCase() === 'create'
- ? await this.collectionsService.createIndex(req.clientId, {
- collection_name,
- extra_params,
- field_name,
- index_name,
- db_name: req.db_name,
- })
- : await this.collectionsService.dropIndex(req.clientId, {
- collection_name,
- field_name,
- index_name,
- db_name: req.db_name,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- async describeIndex(req: Request, res: Response, next: NextFunction) {
- const data = '' + req.query?.collection_name;
- try {
- const result = await this.collectionsService.describeIndex(req.clientId, {
- collection_name: data,
- db_name: req.db_name,
- });
- res.send(result);
- } catch (error) {
- next(error);
- }
- }
- }
|