collections.controller.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. import { NextFunction, Request, Response, Router } from 'express';
  2. import { dtoValidationMiddleware } from '../middlewares/validation';
  3. import { milvusService } from '../milvus';
  4. import { CollectionsService } from './collections.service';
  5. import {
  6. CreateAliasDto,
  7. CreateCollectionDto,
  8. InsertDataDto,
  9. ImportSampleDto,
  10. VectorSearchDto,
  11. QueryDto,
  12. } from './dto';
  13. export class CollectionController {
  14. private collectionsService: CollectionsService;
  15. private router: Router;
  16. constructor() {
  17. this.collectionsService = new CollectionsService(milvusService);
  18. this.router = Router();
  19. }
  20. get collectionsServiceGetter() {
  21. return this.collectionsService;
  22. }
  23. generateRoutes() {
  24. this.router.get('/', this.showCollections.bind(this));
  25. this.router.post(
  26. '/',
  27. dtoValidationMiddleware(CreateCollectionDto),
  28. this.createCollection.bind(this)
  29. );
  30. this.router.get('/statistics', this.getStatistics.bind(this));
  31. this.router.get(
  32. '/:name/statistics',
  33. this.getCollectionStatistics.bind(this)
  34. );
  35. this.router.get(
  36. '/indexes/status',
  37. this.getCollectionsIndexStatus.bind(this)
  38. );
  39. this.router.delete('/:name', this.dropCollection.bind(this));
  40. this.router.get('/:name', this.describeCollection.bind(this));
  41. this.router.put('/:name/load', this.loadCollection.bind(this));
  42. this.router.put('/:name/release', this.releaseCollection.bind(this));
  43. this.router.post(
  44. '/:name/insert',
  45. dtoValidationMiddleware(InsertDataDto),
  46. this.insert.bind(this)
  47. );
  48. this.router.post(
  49. '/:name/importSample',
  50. dtoValidationMiddleware(ImportSampleDto),
  51. this.importSample.bind(this)
  52. );
  53. // we need use req.body, so we can't use delete here
  54. this.router.put('/:name/entities', this.deleteEntities.bind(this));
  55. this.router.post(
  56. '/:name/search',
  57. dtoValidationMiddleware(VectorSearchDto),
  58. this.vectorSearch.bind(this)
  59. );
  60. this.router.post(
  61. '/:name/query',
  62. dtoValidationMiddleware(QueryDto),
  63. this.query.bind(this)
  64. );
  65. this.router.post(
  66. '/:name/alias',
  67. dtoValidationMiddleware(CreateAliasDto),
  68. this.createAlias.bind(this)
  69. );
  70. return this.router;
  71. }
  72. async showCollections(req: Request, res: Response, next: NextFunction) {
  73. const type = parseInt('' + req.query?.type, 10);
  74. try {
  75. const result =
  76. type === 1
  77. ? await this.collectionsService.getLoadedColletions()
  78. : await this.collectionsService.getAllCollections();
  79. res.send(result);
  80. } catch (error) {
  81. next(error);
  82. }
  83. }
  84. async getStatistics(req: Request, res: Response, next: NextFunction) {
  85. try {
  86. const result = await this.collectionsService.getStatistics();
  87. res.send(result);
  88. } catch (error) {
  89. next(error);
  90. }
  91. }
  92. async createCollection(req: Request, res: Response, next: NextFunction) {
  93. const createCollectionData = req.body;
  94. try {
  95. const result = await this.collectionsService.createCollection(
  96. createCollectionData
  97. );
  98. res.send(result);
  99. } catch (error) {
  100. next(error);
  101. }
  102. }
  103. async dropCollection(req: Request, res: Response, next: NextFunction) {
  104. const name = req.params?.name;
  105. try {
  106. const result = await this.collectionsService.dropCollection({
  107. collection_name: name,
  108. });
  109. res.send(result);
  110. } catch (error) {
  111. next(error);
  112. }
  113. }
  114. async describeCollection(req: Request, res: Response, next: NextFunction) {
  115. const name = req.params?.name;
  116. try {
  117. const result = await this.collectionsService.describeCollection({
  118. collection_name: name,
  119. });
  120. res.send(result);
  121. } catch (error) {
  122. next(error);
  123. }
  124. }
  125. async getCollectionStatistics(
  126. req: Request,
  127. res: Response,
  128. next: NextFunction
  129. ) {
  130. const name = req.params?.name;
  131. try {
  132. const result = await this.collectionsService.getCollectionStatistics({
  133. collection_name: name,
  134. });
  135. res.send(result);
  136. } catch (error) {
  137. next(error);
  138. }
  139. }
  140. async getCollectionsIndexStatus(
  141. req: Request,
  142. res: Response,
  143. next: NextFunction
  144. ) {
  145. try {
  146. const result = await this.collectionsService.getCollectionsIndexStatus();
  147. res.send(result);
  148. } catch (error) {
  149. next(error);
  150. }
  151. }
  152. async loadCollection(req: Request, res: Response, next: NextFunction) {
  153. const name = req.params?.name;
  154. try {
  155. const result = await this.collectionsService.loadCollection({
  156. collection_name: name,
  157. });
  158. res.send(result);
  159. } catch (error) {
  160. next(error);
  161. }
  162. }
  163. async releaseCollection(req: Request, res: Response, next: NextFunction) {
  164. const name = req.params?.name;
  165. try {
  166. const result = await this.collectionsService.releaseCollection({
  167. collection_name: name,
  168. });
  169. res.send(result);
  170. } catch (error) {
  171. next(error);
  172. }
  173. }
  174. async insert(req: Request, res: Response, next: NextFunction) {
  175. const name = req.params?.name;
  176. const data = req.body;
  177. try {
  178. const result = await this.collectionsService.insert({
  179. collection_name: name,
  180. ...data,
  181. });
  182. res.send(result);
  183. } catch (error) {
  184. next(error);
  185. }
  186. }
  187. async importSample(req: Request, res: Response, next: NextFunction) {
  188. const data = req.body;
  189. try {
  190. const result = await this.collectionsService.importSample({
  191. ...data,
  192. });
  193. res.send(result);
  194. } catch (error) {
  195. next(error);
  196. }
  197. }
  198. async deleteEntities(req: Request, res: Response, next: NextFunction) {
  199. const name = req.params?.name;
  200. const data = req.body;
  201. try {
  202. const result = await this.collectionsService.deleteEntities({
  203. collection_name: name,
  204. ...data,
  205. });
  206. res.send(result);
  207. } catch (error) {
  208. next(error);
  209. }
  210. }
  211. async vectorSearch(req: Request, res: Response, next: NextFunction) {
  212. const name = req.params?.name;
  213. const data = req.body;
  214. try {
  215. const result = await this.collectionsService.vectorSearch({
  216. collection_name: name,
  217. ...data,
  218. });
  219. res.send(result);
  220. } catch (error) {
  221. next(error);
  222. }
  223. }
  224. async query(req: Request, res: Response, next: NextFunction) {
  225. const name = req.params?.name;
  226. const data = req.body;
  227. const resultiLmit: any = req.query?.limit;
  228. const resultPage: any = req.query?.page;
  229. try {
  230. const limit = isNaN(resultiLmit) ? 100 : parseInt(resultiLmit, 10);
  231. const page = isNaN(resultPage) ? 0 : parseInt(resultPage, 10);
  232. // TODO: add page and limit to node SDK
  233. // Here may raise "Error: 8 RESOURCE_EXHAUSTED: Received message larger than max"
  234. const result = await this.collectionsService.query({
  235. collection_name: name,
  236. ...data,
  237. });
  238. // const queryResultList = result.data;
  239. const queryResultLength = result.data.length;
  240. // const startNum = page * limit;
  241. // const endNum = (page + 1) * limit;
  242. // const slicedResult = queryResultList.slice(startNum, endNum);
  243. // result.data = slicedResult;
  244. res.send({ ...result, limit, page, total: queryResultLength });
  245. } catch (error) {
  246. next(error);
  247. }
  248. }
  249. async createAlias(req: Request, res: Response, next: NextFunction) {
  250. const name = req.params?.name;
  251. const data = req.body;
  252. try {
  253. const result = await this.collectionsService.createAlias({
  254. collection_name: name,
  255. ...data,
  256. });
  257. res.send(result);
  258. } catch (error) {
  259. next(error);
  260. }
  261. }
  262. }