Browse Source

support create multiple vectors in create collection dialog (#481)

Signed-off-by: ryjiang <jiangruiyi@gmail.com>
ryjiang 1 year ago
parent
commit
1e593e20bd

+ 11 - 0
client/src/consts/Milvus.ts

@@ -19,9 +19,20 @@ export enum DataTypeEnum {
   JSON = 23,
   JSON = 23,
   BinaryVector = 100,
   BinaryVector = 100,
   FloatVector = 101,
   FloatVector = 101,
+  Float16Vector = 102,
+  SparseFloatVector = 104,
+  BFloat16Vector = 103,
   Array = 22,
   Array = 22,
 }
 }
 
 
+export const vectorTypes = [
+  DataTypeEnum.BinaryVector,
+  DataTypeEnum.FloatVector,
+  DataTypeEnum.BFloat16Vector,
+  DataTypeEnum.Float16Vector,
+  DataTypeEnum.SparseFloatVector,
+];
+
 export enum INDEX_TYPES_ENUM {
 export enum INDEX_TYPES_ENUM {
   AUTOINDEX = 'AUTOINDEX',
   AUTOINDEX = 'AUTOINDEX',
   IVF_FLAT = 'IVF_FLAT',
   IVF_FLAT = 'IVF_FLAT',

+ 13 - 1
client/src/pages/databases/collections/Constants.ts

@@ -29,10 +29,22 @@ export const VECTOR_FIELDS_OPTIONS: LabelValuePair[] = [
     label: 'Float Vector',
     label: 'Float Vector',
     value: DataTypeEnum.FloatVector,
     value: DataTypeEnum.FloatVector,
   },
   },
+  {
+    label: 'Float16 Vector',
+    value: DataTypeEnum.Float16Vector,
+  },
+  {
+    label: 'BFloat16 Vector',
+    value: DataTypeEnum.BFloat16Vector,
+  },
+  {
+    label: 'Sparse Vector',
+    value: DataTypeEnum.SparseFloatVector,
+  },
 ];
 ];
 
 
 export const ALL_OPTIONS: LabelValuePair[] = [
 export const ALL_OPTIONS: LabelValuePair[] = [
-  // ...VECTOR_FIELDS_OPTIONS,
+  ...VECTOR_FIELDS_OPTIONS,
   {
   {
     label: 'Int8',
     label: 'Int8',
     value: DataTypeEnum.Int8,
     value: DataTypeEnum.Int8,

+ 43 - 16
client/src/pages/databases/collections/CreateFields.tsx

@@ -24,7 +24,7 @@ import {
   VECTOR_FIELDS_OPTIONS,
   VECTOR_FIELDS_OPTIONS,
 } from './Constants';
 } from './Constants';
 import { CreateFieldsProps, CreateFieldType, FieldType } from './Types';
 import { CreateFieldsProps, CreateFieldType, FieldType } from './Types';
-import { DataTypeEnum } from '@/consts';
+import { DataTypeEnum, vectorTypes } from '@/consts';
 import {
 import {
   DEFAULT_ATTU_DIM,
   DEFAULT_ATTU_DIM,
   DEFAULT_ATTU_MAX_CAPACITY,
   DEFAULT_ATTU_MAX_CAPACITY,
@@ -52,7 +52,7 @@ const useStyles = makeStyles((theme: Theme) => ({
     width: '170px',
     width: '170px',
   },
   },
   select: {
   select: {
-    width: '140px',
+    width: '180px',
     marginTop: '-20px',
     marginTop: '-20px',
 
 
     '&:first-child': {
     '&:first-child': {
@@ -242,8 +242,12 @@ const CreateFields: FC<CreateFieldsProps> = ({
     label?: string,
     label?: string,
     className?: string
     className?: string
   ) => {
   ) => {
+    const defaultLabal = collectionTrans(
+      vectorTypes.includes(field.data_type) ? 'vectorFieldName' : 'fieldName'
+    );
+
     return getInput({
     return getInput({
-      label: label || collectionTrans('fieldName'),
+      label: label || defaultLabal,
       value: field.name,
       value: field.name,
       className: className || classes.fieldInput,
       className: className || classes.fieldInput,
       handleChange: (value: string) => {
       handleChange: (value: string) => {
@@ -276,6 +280,10 @@ const CreateFields: FC<CreateFieldsProps> = ({
   };
   };
 
 
   const generateDimension = (field: FieldType) => {
   const generateDimension = (field: FieldType) => {
+    // sparse dont support dimension
+    if (field.data_type === DataTypeEnum.SparseFloatVector) {
+      return null;
+    }
     const validateDimension = (value: string) => {
     const validateDimension = (value: string) => {
       const isPositive = getCheckResult({
       const isPositive = getCheckResult({
         value,
         value,
@@ -456,10 +464,15 @@ const CreateFields: FC<CreateFieldsProps> = ({
 
 
       // remove dimension, if not vector
       // remove dimension, if not vector
       if (
       if (
-        updatedField.data_type !== DataTypeEnum.FloatVector &&
-        updatedField.data_type !== DataTypeEnum.BinaryVector
+        !vectorTypes.includes(updatedField.data_type) ||
+        updatedField.data_type === DataTypeEnum.SparseFloatVector
       ) {
       ) {
         delete updatedField.dimension;
         delete updatedField.dimension;
+      } else {
+        // add dimension if not exist
+        updatedField.dimension = Number(
+          updatedField.dimension || DEFAULT_ATTU_DIM
+        );
       }
       }
 
 
       return updatedField;
       return updatedField;
@@ -551,18 +564,15 @@ const CreateFields: FC<CreateFieldsProps> = ({
   ): ReactElement => {
   ): ReactElement => {
     return (
     return (
       <div className={`${classes.rowWrapper}`}>
       <div className={`${classes.rowWrapper}`}>
-        {generateFieldName(field, collectionTrans('vectorFieldName'))}
-
+        {generateFieldName(field)}
         {getSelector(
         {getSelector(
           'vector',
           'vector',
           `${collectionTrans('vectorType')} `,
           `${collectionTrans('vectorType')} `,
           field.data_type,
           field.data_type,
           (value: DataTypeEnum) => changeFields(field.id!, 'data_type', value)
           (value: DataTypeEnum) => changeFields(field.id!, 'data_type', value)
         )}
         )}
-        {generateDesc(field)}
-
         {generateDimension(field)}
         {generateDimension(field)}
-
+        {generateDesc(field)}
         <IconButton
         <IconButton
           onClick={() => handleAddNewField(index)}
           onClick={() => handleAddNewField(index)}
           classes={{ root: classes.iconBtn }}
           classes={{ root: classes.iconBtn }}
@@ -643,12 +653,9 @@ const CreateFields: FC<CreateFieldsProps> = ({
     );
     );
   };
   };
 
 
-  const generateVectorRow = (field: FieldType) => {
+  const generateVectorRow = (field: FieldType, index: number) => {
     return (
     return (
       <div className={`${classes.rowWrapper}`}>
       <div className={`${classes.rowWrapper}`}>
-        <IconButton classes={{ root: classes.iconBtn }} aria-label="delete">
-          <RemoveIcon />
-        </IconButton>
         {generateFieldName(field)}
         {generateFieldName(field)}
         {getSelector(
         {getSelector(
           'all',
           'all',
@@ -656,9 +663,29 @@ const CreateFields: FC<CreateFieldsProps> = ({
           field.data_type,
           field.data_type,
           (value: DataTypeEnum) => changeFields(field.id!, 'data_type', value)
           (value: DataTypeEnum) => changeFields(field.id!, 'data_type', value)
         )}
         )}
-        {generateDimension(field)}
 
 
+        {generateDimension(field)}
         {generateDesc(field)}
         {generateDesc(field)}
+
+        <IconButton
+          onClick={() => {
+            handleAddNewField(index);
+          }}
+          classes={{ root: classes.iconBtn }}
+          aria-label="add"
+        >
+          <AddIcon />
+        </IconButton>
+        <IconButton
+          onClick={() => {
+            const id = field.id || '';
+            handleRemoveField(id);
+          }}
+          classes={{ root: classes.iconBtn }}
+          aria-label="delete"
+        >
+          <RemoveIcon />
+        </IconButton>
       </div>
       </div>
     );
     );
   };
   };
@@ -683,7 +710,7 @@ const CreateFields: FC<CreateFieldsProps> = ({
   ) => {
   ) => {
     // optional type is vector or number
     // optional type is vector or number
     if (field.createType === 'vector') {
     if (field.createType === 'vector') {
-      return generateVectorRow(field);
+      return generateVectorRow(field, index);
     }
     }
 
 
     // use number as default createType
     // use number as default createType

+ 15 - 4
client/src/pages/dialogs/CreateCollectionDialog.tsx

@@ -13,7 +13,12 @@ import { ITextfieldConfig } from '@/components/customInput/Types';
 import { rootContext, dataContext } from '@/context';
 import { rootContext, dataContext } from '@/context';
 import { useFormValidation } from '@/hooks';
 import { useFormValidation } from '@/hooks';
 import { formatForm, TypeEnum } from '@/utils';
 import { formatForm, TypeEnum } from '@/utils';
-import { DataTypeEnum, ConsistencyLevelEnum, DEFAULT_ATTU_DIM } from '@/consts';
+import {
+  DataTypeEnum,
+  ConsistencyLevelEnum,
+  DEFAULT_ATTU_DIM,
+  vectorTypes,
+} from '@/consts';
 import CreateFields from '../databases/collections/CreateFields';
 import CreateFields from '../databases/collections/CreateFields';
 import {
 import {
   CollectionCreateParam,
   CollectionCreateParam,
@@ -49,7 +54,7 @@ const useStyles = makeStyles((theme: Theme) => ({
     width: '100%',
     width: '100%',
   },
   },
   select: {
   select: {
-    width: '160px',
+    width: '170px',
 
 
     '&:first-child': {
     '&:first-child': {
       marginLeft: 0,
       marginLeft: 0,
@@ -201,7 +206,6 @@ const CreateCollectionDialog: FC<CollectionCreateProps> = ({ onCreate }) => {
   ];
   ];
 
 
   const handleCreateCollection = async () => {
   const handleCreateCollection = async () => {
-    const vectorType = [DataTypeEnum.BinaryVector, DataTypeEnum.FloatVector];
     const param: CollectionCreateParam = {
     const param: CollectionCreateParam = {
       ...form,
       ...form,
       fields: fields.map(v => {
       fields: fields.map(v => {
@@ -229,7 +233,7 @@ const CreateCollectionDialog: FC<CollectionCreateProps> = ({ onCreate }) => {
 
 
         v.is_primary_key && (data.autoID = form.autoID);
         v.is_primary_key && (data.autoID = form.autoID);
 
 
-        return vectorType.includes(v.data_type)
+        const param = vectorTypes.includes(v.data_type)
           ? {
           ? {
               ...data,
               ...data,
               type_params: {
               type_params: {
@@ -246,6 +250,13 @@ const CreateCollectionDialog: FC<CollectionCreateProps> = ({ onCreate }) => {
               },
               },
             }
             }
           : { ...data };
           : { ...data };
+
+        // delete sparse vector dime
+        if (param.data_type === DataTypeEnum.SparseFloatVector) {
+          delete param.type_params!.dim;
+        }
+
+        return param;
       }),
       }),
       consistency_level: consistencyLevel,
       consistency_level: consistencyLevel,
     };
     };

+ 5 - 2
client/src/utils/Format.ts

@@ -3,8 +3,12 @@ import {
   DEFAULT_MILVUS_PORT,
   DEFAULT_MILVUS_PORT,
   DEFAULT_PROMETHEUS_PORT,
   DEFAULT_PROMETHEUS_PORT,
   DataTypeEnum,
   DataTypeEnum,
+  vectorTypes,
 } from '@/consts';
 } from '@/consts';
-import { CreateFieldType, CreateField } from '@/pages/databases/collections/Types';
+import {
+  CreateFieldType,
+  CreateField,
+} from '@/pages/databases/collections/Types';
 import { FieldObject } from '@server/types';
 import { FieldObject } from '@server/types';
 
 
 /**
 /**
@@ -104,7 +108,6 @@ export const getCreateFieldType = (config: CreateField): CreateFieldType => {
     return 'defaultVector';
     return 'defaultVector';
   }
   }
 
 
-  const vectorTypes = [DataTypeEnum.BinaryVector, DataTypeEnum.FloatVector];
   if (vectorTypes.includes(config.data_type)) {
   if (vectorTypes.includes(config.data_type)) {
     return 'vector';
     return 'vector';
   }
   }