collections.controller.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. import { NextFunction, Request, Response, Router } from 'express';
  2. import { dtoValidationMiddleware } from '../middleware/validation';
  3. import { CollectionsService } from './collections.service';
  4. import { LoadCollectionReq } from '@zilliz/milvus2-sdk-node';
  5. import {
  6. CreateAliasDto,
  7. CreateCollectionDto,
  8. InsertDataDto,
  9. ImportSampleDto,
  10. VectorSearchDto,
  11. QueryDto,
  12. RenameCollectionDto,
  13. DuplicateCollectionDto,
  14. ManageIndexDto,
  15. } from './dto';
  16. export class CollectionController {
  17. private collectionsService: CollectionsService;
  18. private router: Router;
  19. constructor() {
  20. this.collectionsService = new CollectionsService();
  21. this.router = Router();
  22. }
  23. get collectionsServiceGetter() {
  24. return this.collectionsService;
  25. }
  26. generateRoutes() {
  27. // get all collections
  28. this.router.get('/', this.showCollections.bind(this));
  29. // get all collections statistics
  30. this.router.get('/statistics', this.getStatistics.bind(this));
  31. // index
  32. this.router.post(
  33. '/index',
  34. dtoValidationMiddleware(ManageIndexDto),
  35. this.manageIndex.bind(this)
  36. );
  37. this.router.get('/index', this.describeIndex.bind(this));
  38. this.router.post('/index/flush', this.clearCache.bind(this));
  39. // get collection with index info
  40. this.router.get('/:name', this.describeCollection.bind(this));
  41. // get count
  42. this.router.get('/:name/count', this.count.bind(this));
  43. // create collection
  44. this.router.post(
  45. '/',
  46. dtoValidationMiddleware(CreateCollectionDto),
  47. this.createCollection.bind(this)
  48. );
  49. // drop collection
  50. this.router.delete('/:name', this.dropCollection.bind(this));
  51. // rename collection
  52. this.router.post(
  53. '/:name',
  54. dtoValidationMiddleware(RenameCollectionDto),
  55. this.renameCollection.bind(this)
  56. );
  57. // duplicate collection
  58. this.router.post(
  59. '/:name/duplicate',
  60. dtoValidationMiddleware(DuplicateCollectionDto),
  61. this.duplicateCollection.bind(this)
  62. );
  63. // get collection statistics
  64. this.router.get(
  65. '/:name/statistics',
  66. this.getCollectionStatistics.bind(this)
  67. );
  68. // load / release
  69. this.router.put('/:name/load', this.loadCollection.bind(this));
  70. this.router.put('/:name/release', this.releaseCollection.bind(this));
  71. this.router.put('/:name/empty', this.empty.bind(this));
  72. // insert data
  73. this.router.post(
  74. '/:name/insert',
  75. dtoValidationMiddleware(InsertDataDto),
  76. this.insert.bind(this)
  77. );
  78. // insert sample data
  79. this.router.post(
  80. '/:name/importSample',
  81. dtoValidationMiddleware(ImportSampleDto),
  82. this.importSample.bind(this)
  83. );
  84. // we need use req.body, so we can't use delete here
  85. this.router.put('/:name/entities', this.deleteEntities.bind(this));
  86. this.router.post(
  87. '/:name/search',
  88. dtoValidationMiddleware(VectorSearchDto),
  89. this.vectorSearch.bind(this)
  90. );
  91. // query
  92. this.router.post(
  93. '/:name/query',
  94. dtoValidationMiddleware(QueryDto),
  95. this.query.bind(this)
  96. );
  97. // create alias
  98. this.router.post(
  99. '/:name/alias',
  100. dtoValidationMiddleware(CreateAliasDto),
  101. this.createAlias.bind(this)
  102. );
  103. // drop alias
  104. this.router.delete('/:name/alias/:alias', this.dropAlias.bind(this));
  105. // segments
  106. this.router.get('/:name/psegments', this.getPSegment.bind(this));
  107. this.router.get('/:name/qsegments', this.getQSegment.bind(this));
  108. // compact
  109. this.router.put('/:name/compact', this.compact.bind(this));
  110. return this.router;
  111. }
  112. async showCollections(req: Request, res: Response, next: NextFunction) {
  113. const type = parseInt('' + req.query?.type, 10);
  114. try {
  115. const result =
  116. type === 1
  117. ? await this.collectionsService.getLoadedCollections(req.clientId)
  118. : await this.collectionsService.getAllCollections(req.clientId);
  119. res.send(result);
  120. } catch (error) {
  121. next(error);
  122. }
  123. }
  124. async getStatistics(req: Request, res: Response, next: NextFunction) {
  125. try {
  126. const result = await this.collectionsService.getStatistics(req.clientId);
  127. res.send(result);
  128. } catch (error) {
  129. next(error);
  130. }
  131. }
  132. async createCollection(req: Request, res: Response, next: NextFunction) {
  133. const createCollectionData = req.body;
  134. try {
  135. const result = await this.collectionsService.createCollection(
  136. req.clientId,
  137. createCollectionData
  138. );
  139. res.send(result);
  140. } catch (error) {
  141. next(error);
  142. }
  143. }
  144. async renameCollection(req: Request, res: Response, next: NextFunction) {
  145. const name = req.params?.name;
  146. const data = req.body;
  147. try {
  148. const result = await this.collectionsService.renameCollection(
  149. req.clientId,
  150. {
  151. collection_name: name,
  152. ...data,
  153. }
  154. );
  155. res.send(result);
  156. } catch (error) {
  157. next(error);
  158. }
  159. }
  160. async duplicateCollection(req: Request, res: Response, next: NextFunction) {
  161. const name = req.params?.name;
  162. const data = req.body;
  163. try {
  164. const result = await this.collectionsService.duplicateCollection(
  165. req.clientId,
  166. {
  167. collection_name: name,
  168. ...data,
  169. }
  170. );
  171. res.send(result);
  172. } catch (error) {
  173. next(error);
  174. }
  175. }
  176. async dropCollection(req: Request, res: Response, next: NextFunction) {
  177. const name = req.params?.name;
  178. try {
  179. const result = await this.collectionsService.dropCollection(
  180. req.clientId,
  181. {
  182. collection_name: name,
  183. }
  184. );
  185. res.send(result);
  186. } catch (error) {
  187. next(error);
  188. }
  189. }
  190. async describeCollection(req: Request, res: Response, next: NextFunction) {
  191. const name = req.params?.name;
  192. try {
  193. const result = await this.collectionsService.getAllCollections(
  194. req.clientId,
  195. [name]
  196. );
  197. res.send(result[0]);
  198. } catch (error) {
  199. next(error);
  200. }
  201. }
  202. async getCollectionStatistics(
  203. req: Request,
  204. res: Response,
  205. next: NextFunction
  206. ) {
  207. const name = req.params?.name;
  208. try {
  209. const result = await this.collectionsService.getCollectionStatistics(
  210. req.clientId,
  211. {
  212. collection_name: name,
  213. }
  214. );
  215. res.send(result);
  216. } catch (error) {
  217. next(error);
  218. }
  219. }
  220. async loadCollection(req: Request, res: Response, next: NextFunction) {
  221. const collection_name = req.params?.name;
  222. const data = req.body;
  223. const param: LoadCollectionReq = { collection_name };
  224. if (data.replica_number) {
  225. param.replica_number = Number(data.replica_number);
  226. }
  227. try {
  228. const result = await this.collectionsService.loadCollection(
  229. req.clientId,
  230. param
  231. );
  232. res.send(result);
  233. } catch (error) {
  234. next(error);
  235. }
  236. }
  237. async releaseCollection(req: Request, res: Response, next: NextFunction) {
  238. const name = req.params?.name;
  239. try {
  240. const result = await this.collectionsService.releaseCollection(
  241. req.clientId,
  242. {
  243. collection_name: name,
  244. }
  245. );
  246. res.send(result);
  247. } catch (error) {
  248. next(error);
  249. }
  250. }
  251. async insert(req: Request, res: Response, next: NextFunction) {
  252. const name = req.params?.name;
  253. const data = req.body;
  254. try {
  255. const result = await this.collectionsService.insert(req.clientId, {
  256. collection_name: name,
  257. ...data,
  258. });
  259. res.send(result);
  260. } catch (error) {
  261. next(error);
  262. }
  263. }
  264. async importSample(req: Request, res: Response, next: NextFunction) {
  265. const data = req.body;
  266. try {
  267. const result = await this.collectionsService.importSample(req.clientId, {
  268. ...data,
  269. });
  270. res.send(result);
  271. } catch (error) {
  272. next(error);
  273. }
  274. }
  275. async deleteEntities(req: Request, res: Response, next: NextFunction) {
  276. const name = req.params?.name;
  277. const data = req.body;
  278. try {
  279. const result = await this.collectionsService.deleteEntities(
  280. req.clientId,
  281. {
  282. collection_name: name,
  283. ...data,
  284. }
  285. );
  286. res.send(result);
  287. } catch (error) {
  288. next(error);
  289. }
  290. }
  291. async vectorSearch(req: Request, res: Response, next: NextFunction) {
  292. const name = req.params?.name;
  293. const data = req.body;
  294. try {
  295. const result = await this.collectionsService.vectorSearch(req.clientId, {
  296. collection_name: name,
  297. ...data,
  298. });
  299. res.send(result);
  300. } catch (error) {
  301. next(error);
  302. }
  303. }
  304. async query(req: Request, res: Response, next: NextFunction) {
  305. const name = req.params?.name;
  306. const data = req.body;
  307. const resultLimit: any = req.query?.limit;
  308. const resultPage: any = req.query?.page;
  309. try {
  310. const limit = parseInt(resultLimit, 10);
  311. const page = isNaN(resultPage) ? 0 : parseInt(resultPage, 10);
  312. const result = await this.collectionsService.query(req.clientId, {
  313. collection_name: name,
  314. ...data,
  315. });
  316. // const queryResultList = result.data;
  317. const queryResultLength = result.data.length;
  318. res.send({ ...result, limit, page, total: queryResultLength });
  319. } catch (error) {
  320. next(error);
  321. }
  322. }
  323. async createAlias(req: Request, res: Response, next: NextFunction) {
  324. const name = req.params?.name;
  325. const data = req.body;
  326. try {
  327. const result = await this.collectionsService.createAlias(req.clientId, {
  328. collection_name: name,
  329. ...data,
  330. });
  331. res.send(result);
  332. } catch (error) {
  333. next(error);
  334. }
  335. }
  336. async dropAlias(req: Request, res: Response, next: NextFunction) {
  337. const alias = req.params?.alias;
  338. const name = req.params?.name;
  339. try {
  340. const result = await this.collectionsService.dropAlias(
  341. req.clientId,
  342. name,
  343. {
  344. alias,
  345. }
  346. );
  347. res.send(result);
  348. } catch (error) {
  349. next(error);
  350. }
  351. }
  352. async getReplicas(req: Request, res: Response, next: NextFunction) {
  353. const collectionID = req.params?.collectionID;
  354. try {
  355. const result = await this.collectionsService.getReplicas(req.clientId, {
  356. collectionID,
  357. });
  358. res.send(result);
  359. } catch (error) {
  360. next(error);
  361. }
  362. }
  363. async getPSegment(req: Request, res: Response, next: NextFunction) {
  364. const name = req.params?.name;
  365. try {
  366. const result = await this.collectionsService.getPersistentSegmentInfo(
  367. req.clientId,
  368. {
  369. collectionName: name,
  370. }
  371. );
  372. res.send(result.infos);
  373. } catch (error) {
  374. next(error);
  375. }
  376. }
  377. async getQSegment(req: Request, res: Response, next: NextFunction) {
  378. const name = req.params?.name;
  379. try {
  380. const result = await this.collectionsService.getQuerySegmentInfo(
  381. req.clientId,
  382. {
  383. collectionName: name,
  384. }
  385. );
  386. res.send(result.infos);
  387. } catch (error) {
  388. next(error);
  389. }
  390. }
  391. async compact(req: Request, res: Response, next: NextFunction) {
  392. const name = req.params?.name;
  393. try {
  394. const result = await this.collectionsService.compact(req.clientId, {
  395. collection_name: name,
  396. });
  397. res.send(result);
  398. } catch (error) {
  399. next(error);
  400. }
  401. }
  402. async count(req: Request, res: Response, next: NextFunction) {
  403. const name = req.params?.name;
  404. try {
  405. const result = await this.collectionsService.count(req.clientId, {
  406. collection_name: name,
  407. });
  408. res.send(result);
  409. } catch (error) {
  410. next(error);
  411. }
  412. }
  413. async empty(req: Request, res: Response, next: NextFunction) {
  414. const name = req.params?.name;
  415. try {
  416. const result = await this.collectionsService.emptyCollection(
  417. req.clientId,
  418. {
  419. collection_name: name,
  420. }
  421. );
  422. res.send(result);
  423. } catch (error) {
  424. next(error);
  425. }
  426. }
  427. async manageIndex(req: Request, res: Response, next: NextFunction) {
  428. const { type, collection_name, index_name, extra_params, field_name } =
  429. req.body;
  430. try {
  431. const result =
  432. type.toLocaleLowerCase() === 'create'
  433. ? await this.collectionsService.createIndex(req.clientId, {
  434. collection_name,
  435. extra_params,
  436. field_name,
  437. index_name,
  438. })
  439. : await this.collectionsService.dropIndex(req.clientId, {
  440. collection_name,
  441. field_name,
  442. index_name,
  443. });
  444. res.send(result);
  445. } catch (error) {
  446. next(error);
  447. }
  448. }
  449. async describeIndex(req: Request, res: Response, next: NextFunction) {
  450. const data = '' + req.query?.collection_name;
  451. try {
  452. const result = await this.collectionsService.describeIndex(req.clientId, {
  453. collection_name: data,
  454. });
  455. res.send(result);
  456. } catch (error) {
  457. next(error);
  458. }
  459. }
  460. async clearCache(req: Request, res: Response, next: NextFunction) {
  461. try {
  462. const result = await this.collectionsService.clearCache(req.clientId);
  463. res.send(result);
  464. } catch (error) {
  465. next(error);
  466. }
  467. }
  468. }