Переглянути джерело

Merge pull request #247 from nameczz/dev

add collection alias and update sdk
ryjiang 3 роки тому
батько
коміт
c1719b0dc2

+ 2 - 0
client/src/components/icons/Icons.tsx

@@ -21,6 +21,7 @@ import RemoveCircleOutlineIcon from '@material-ui/icons/RemoveCircleOutline';
 import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
 import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
 import CachedIcon from '@material-ui/icons/Cached';
 import CachedIcon from '@material-ui/icons/Cached';
 import FilterListIcon from '@material-ui/icons/FilterList';
 import FilterListIcon from '@material-ui/icons/FilterList';
+import AlternateEmailIcon from '@material-ui/icons/AlternateEmail';
 import { SvgIcon } from '@material-ui/core';
 import { SvgIcon } from '@material-ui/core';
 import { ReactComponent as MilvusIcon } from '../../assets/icons/milvus.svg';
 import { ReactComponent as MilvusIcon } from '../../assets/icons/milvus.svg';
 import { ReactComponent as OverviewIcon } from '../../assets/icons/overview.svg';
 import { ReactComponent as OverviewIcon } from '../../assets/icons/overview.svg';
@@ -58,6 +59,7 @@ const icons: { [x in IconsType]: (props?: any) => React.ReactElement } = {
   dropdown: (props = {}) => <ArrowDropDownIcon {...props} />,
   dropdown: (props = {}) => <ArrowDropDownIcon {...props} />,
   refresh: (props = {}) => <CachedIcon {...props} />,
   refresh: (props = {}) => <CachedIcon {...props} />,
   filter: (props = {}) => <FilterListIcon {...props} />,
   filter: (props = {}) => <FilterListIcon {...props} />,
+  alias: (props = {}) => <AlternateEmailIcon {...props} />,
 
 
   milvus: (props = {}) => (
   milvus: (props = {}) => (
     <SvgIcon viewBox="0 0 44 31" component={MilvusIcon} {...props} />
     <SvgIcon viewBox="0 0 44 31" component={MilvusIcon} {...props} />

+ 2 - 1
client/src/components/icons/Types.ts

@@ -32,4 +32,5 @@ export type IconsType =
   | 'vectorSearch'
   | 'vectorSearch'
   | 'refresh'
   | 'refresh'
   | 'filter'
   | 'filter'
-  | 'copyExpression';
+  | 'copyExpression'
+  | 'alias';

+ 7 - 0
client/src/http/Collection.ts

@@ -91,6 +91,13 @@ export class CollectionHttp extends BaseModel implements CollectionView {
     });
     });
   }
   }
 
 
+  static createAlias(collectionName: string, params: { alias: string }) {
+    return super.create({
+      path: `${this.COLLECTIONS_URL}/${collectionName}/alias`,
+      data: params,
+    });
+  }
+
   get _autoId() {
   get _autoId() {
     return this.autoID;
     return this.autoID;
   }
   }

+ 2 - 0
client/src/i18n/cn/collection.ts

@@ -8,6 +8,8 @@ const collectionTrans = {
   create: 'Create Collection',
   create: 'Create Collection',
   delete: 'delete',
   delete: 'delete',
   deleteTooltip: 'Please select at least one item to delete.',
   deleteTooltip: 'Please select at least one item to delete.',
+  alias: 'alias',
+  aliasTooltip: 'Please select one collection to create alias',
 
 
   collection: 'Collection',
   collection: 'Collection',
 
 

+ 1 - 0
client/src/i18n/cn/dialog.ts

@@ -2,6 +2,7 @@ const dialogTrans = {
   deleteTipAction: 'Type',
   deleteTipAction: 'Type',
   deleteTipPurpose: 'to confirm.',
   deleteTipPurpose: 'to confirm.',
   deleteTitle: `Delete {{type}}`,
   deleteTitle: `Delete {{type}}`,
+  createAlias: `Create alias for {{type}}`,
 
 
   releaseTitle: `Release {{type}}`,
   releaseTitle: `Release {{type}}`,
   loadTitle: `Load {{type}}`,
   loadTitle: `Load {{type}}`,

+ 2 - 0
client/src/i18n/en/collection.ts

@@ -8,6 +8,8 @@ const collectionTrans = {
   create: 'Create Collection',
   create: 'Create Collection',
   delete: 'delete',
   delete: 'delete',
   deleteTooltip: 'Please select at least one item to delete.',
   deleteTooltip: 'Please select at least one item to delete.',
+  alias: 'alias',
+  aliasTooltip: 'Please select one collection to create alias',
 
 
   collection: 'Collection',
   collection: 'Collection',
 
 

+ 1 - 0
client/src/i18n/en/dialog.ts

@@ -3,6 +3,7 @@ const dialogTrans = {
   deleteTipPurpose: 'to confirm.',
   deleteTipPurpose: 'to confirm.',
   deleteTitle: `Delete {{type}}`,
   deleteTitle: `Delete {{type}}`,
   releaseTitle: `Release {{type}}`,
   releaseTitle: `Release {{type}}`,
+  createAlias: `Create alias for {{type}}`,
   loadTitle: `Load {{type}}`,
   loadTitle: `Load {{type}}`,
 
 
   loadContent: `You are trying to load a {{type}} with data. Only loaded {{type}} can be searched.`,
   loadContent: `You are trying to load a {{type}} with data. Only loaded {{type}} can be searched.`,

+ 24 - 0
client/src/pages/collections/Collections.tsx

@@ -36,6 +36,7 @@ import { LOADING_STATE } from '../../consts/Milvus';
 import { webSokcetContext } from '../../context/WebSocket';
 import { webSokcetContext } from '../../context/WebSocket';
 import { WS_EVENTS, WS_EVENTS_TYPE } from '../../consts/Http';
 import { WS_EVENTS, WS_EVENTS_TYPE } from '../../consts/Http';
 import { checkIndexBuilding, checkLoading } from '../../utils/Validation';
 import { checkIndexBuilding, checkLoading } from '../../utils/Validation';
+import CreateAlias from './CreateAlias';
 
 
 const useStyles = makeStyles((theme: Theme) => ({
 const useStyles = makeStyles((theme: Theme) => ({
   emptyWrapper: {
   emptyWrapper: {
@@ -307,6 +308,29 @@ const Collections = () => {
       disabledTooltip: collectionTrans('deleteTooltip'),
       disabledTooltip: collectionTrans('deleteTooltip'),
       disabled: data => data.length === 0,
       disabled: data => data.length === 0,
     },
     },
+    {
+      type: 'iconBtn',
+      onClick: () => {
+        setDialog({
+          open: true,
+          type: 'custom',
+          params: {
+            component: (
+              <CreateAlias
+                collectionName={selectedCollections[0]._name}
+                cb={() => {
+                  setSelectedCollections([]);
+                }}
+              />
+            ),
+          },
+        });
+      },
+      label: collectionTrans('alias'),
+      icon: 'alias',
+      disabledTooltip: collectionTrans('aliasTooltip'),
+      disabled: data => data.length !== 1,
+    },
     {
     {
       label: 'Search',
       label: 'Search',
       icon: 'search',
       icon: 'search',

+ 84 - 0
client/src/pages/collections/CreateAlias.tsx

@@ -0,0 +1,84 @@
+import { FC, useContext, useMemo, useState } from 'react';
+
+import { useTranslation } from 'react-i18next';
+import { rootContext } from '../../context/Root';
+
+import DialogTemplate from '../../components/customDialog/DialogTemplate';
+
+import CustomInput from '../../components/customInput/CustomInput';
+import { formatForm } from '../../utils/Form';
+import { useFormValidation } from '../../hooks/Form';
+import { ITextfieldConfig } from '../../components/customInput/Types';
+import { CollectionHttp } from '../../http/Collection';
+import { CreateAliasProps } from './Types';
+
+const CreateAlias: FC<CreateAliasProps> = props => {
+  const { cb, collectionName } = props;
+  const [form, setForm] = useState({
+    alias: '',
+  });
+
+  const checkedForm = useMemo(() => {
+    const { alias } = form;
+    return formatForm({ alias });
+  }, [form]);
+
+  const { validation, checkIsValid, disabled } = useFormValidation(checkedForm);
+
+  const { handleCloseDialog } = useContext(rootContext);
+  const { t: dialogTrans } = useTranslation('dialog');
+  const { t: warningTrans } = useTranslation('warning');
+  const { t: collectionTrans } = useTranslation('collection');
+
+  const handleInputChange = (value: string) => {
+    setForm({ alias: value });
+  };
+
+  const handleConfirm = async () => {
+    await CollectionHttp.createAlias(collectionName, form);
+    handleCloseDialog();
+    cb && cb();
+  };
+
+  const aliasInputConfig: ITextfieldConfig = {
+    label: 'Collection Alias',
+    key: 'alias',
+    onChange: handleInputChange,
+    variant: 'filled',
+    placeholder: 'alias name',
+    fullWidth: true,
+    validations: [
+      {
+        rule: 'require',
+        errorText: warningTrans('required', {
+          name: collectionTrans('name'),
+        }),
+      },
+      {
+        rule: 'collectionName',
+        errorText: collectionTrans('nameContentWarning'),
+      },
+    ],
+    defaultValue: form.alias,
+  };
+  return (
+    <DialogTemplate
+      title={dialogTrans('createAlias', {
+        type: collectionName,
+      })}
+      handleClose={handleCloseDialog}
+      children={
+        <CustomInput
+          type="text"
+          textConfig={aliasInputConfig}
+          checkValid={checkIsValid}
+          validInfo={validation}
+        />
+      }
+      handleConfirm={handleConfirm}
+      confirmDisabled={disabled}
+    />
+  );
+};
+
+export default CreateAlias;

+ 6 - 2
client/src/pages/collections/Types.ts

@@ -6,7 +6,7 @@ import { FieldData } from '../schema/Types';
 export interface CollectionData {
 export interface CollectionData {
   _name: string;
   _name: string;
   _id: string;
   _id: string;
-  _loadedPercentage:string;
+  _loadedPercentage: string;
   _status: LOADING_STATE;
   _status: LOADING_STATE;
   _rowCount: string;
   _rowCount: string;
   _desc: string;
   _desc: string;
@@ -76,11 +76,15 @@ export interface CreateFieldsProps {
   fields: Field[];
   fields: Field[];
   setFields: Dispatch<SetStateAction<Field[]>>;
   setFields: Dispatch<SetStateAction<Field[]>>;
   setFieldsValidation: Dispatch<
   setFieldsValidation: Dispatch<
-    SetStateAction<{ [x: string]: string | boolean; }[]>
+    SetStateAction<{ [x: string]: string | boolean }[]>
   >;
   >;
   autoID: boolean;
   autoID: boolean;
   setAutoID: (value: boolean) => void;
   setAutoID: (value: boolean) => void;
 }
 }
+export interface CreateAliasProps {
+  collectionName: string;
+  cb?: () => void;
+}
 
 
 export interface InsertDataParam {
 export interface InsertDataParam {
   partition_names: string[];
   partition_names: string[];

+ 1 - 1
express/package.json

@@ -4,7 +4,7 @@
   "main": "dist/app.js",
   "main": "dist/app.js",
   "license": "MIT",
   "license": "MIT",
   "dependencies": {
   "dependencies": {
-    "@zilliz/milvus2-sdk-node": "^1.0.18",
+    "@zilliz/milvus2-sdk-node": "^1.0.19",
     "cors": "^2.8.5",
     "cors": "^2.8.5",
     "cross-env": "^7.0.3",
     "cross-env": "^7.0.3",
     "express": "^4.17.1",
     "express": "^4.17.1",

+ 21 - 0
express/src/collections/collections.service.ts

@@ -14,6 +14,9 @@ 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";
 import {
 import {
+  AlterAliasReq,
+  CreateAliasReq,
+  DropAliasReq,
   ShowCollectionsReq,
   ShowCollectionsReq,
   ShowCollectionsType,
   ShowCollectionsType,
 } from "@zilliz/milvus2-sdk-node/dist/milvus/types/Collection";
 } from "@zilliz/milvus2-sdk-node/dist/milvus/types/Collection";
@@ -87,6 +90,24 @@ export class CollectionsService {
     return res;
     return res;
   }
   }
 
 
+  async createAlias(data: CreateAliasReq) {
+    const res = await this.collectionManager.createAlias(data);
+    throwErrorFromSDK(res);
+    return res;
+  }
+
+  async alterAlias(data: AlterAliasReq) {
+    const res = await this.collectionManager.alterAlias(data);
+    throwErrorFromSDK(res);
+    return res;
+  }
+
+  async dropAlias(data: DropAliasReq) {
+    const res = await this.collectionManager.dropAlias(data);
+    throwErrorFromSDK(res);
+    return res;
+  }
+
   /**
   /**
    * We do not throw error for this.
    * We do not throw error for this.
    * Because if collection dont have index, it will throw error.
    * Because if collection dont have index, it will throw error.

+ 14 - 0
express/src/collections/index.ts

@@ -127,4 +127,18 @@ router.post("/:name/search", async (req, res, next) => {
   }
   }
 });
 });
 
 
+router.post("/:name/alias", async (req, res, next) => {
+  const name = req.params?.name;
+  const data = req.body;
+  try {
+    const result = await collectionsService.createAlias({
+      collection_name: name,
+      ...data,
+    });
+    res.send(result);
+  } catch (error) {
+    next(error);
+  }
+});
+
 export { router };
 export { router };

+ 4 - 4
express/yarn.lock

@@ -332,10 +332,10 @@
   dependencies:
   dependencies:
     "@types/node" "*"
     "@types/node" "*"
 
 
-"@zilliz/milvus2-sdk-node@^1.0.18":
-  version "1.0.18"
-  resolved "https://registry.yarnpkg.com/@zilliz/milvus2-sdk-node/-/milvus2-sdk-node-1.0.18.tgz#8f445823a952d8dfff5e057c496d19d67c891f81"
-  integrity sha512-D7N/2W1fwWlhm0dM4Y/+tph5O6v2Qa3Phbux6CIlz4LocX+Z/rt5L0OLInrNLPNZSkaHz+AxbDz1MLdeqiOZkg==
+"@zilliz/milvus2-sdk-node@^1.0.19":
+  version "1.0.19"
+  resolved "https://registry.yarnpkg.com/@zilliz/milvus2-sdk-node/-/milvus2-sdk-node-1.0.19.tgz#966e68a2d88e62ba475a138b382fb71209670a2e"
+  integrity sha512-LMRRM+vU+AiB3ETUAzIgiFxVZJJ63vyuEP7cZevz4tQPXUW1tN63MVCWFVikQKx3QNE+ikArnoQIGJc0I9+kEA==
   dependencies:
   dependencies:
     "@grpc/grpc-js" "^1.2.12"
     "@grpc/grpc-js" "^1.2.12"
     "@grpc/proto-loader" "^0.6.0"
     "@grpc/proto-loader" "^0.6.0"