Browse Source

support bool field

Signed-off-by: Gitea <zizhao.chen@zilliz.com>
Gitea 3 years ago
parent
commit
fb9b02569a

+ 19 - 37
client/src/components/advancedSearch/Condition.tsx

@@ -1,4 +1,4 @@
-import React, { useState, useEffect, FC } from 'react';
+import React, { useState, useEffect, FC, useMemo } from 'react';
 import {
 import {
   makeStyles,
   makeStyles,
   Theme,
   Theme,
@@ -9,39 +9,7 @@ import {
 import CloseIcon from '@material-ui/icons/Close';
 import CloseIcon from '@material-ui/icons/Close';
 import { ConditionProps, Field } from './Types';
 import { ConditionProps, Field } from './Types';
 import CustomSelector from '../customSelector/CustomSelector';
 import CustomSelector from '../customSelector/CustomSelector';
-
-// Todo: Move to corrsponding Constant file.
-// Static logical operators.
-const LogicalOperators = [
-  {
-    value: '<',
-    label: '<',
-  },
-  {
-    value: '<=',
-    label: '<=',
-  },
-  {
-    value: '>',
-    label: '>',
-  },
-  {
-    value: '>=',
-    label: '>=',
-  },
-  {
-    value: '==',
-    label: '==',
-  },
-  {
-    value: '!=',
-    label: '!=',
-  },
-  {
-    value: 'in',
-    label: 'in',
-  },
-];
+import { LOGICAL_OPERATORS } from '../../consts/Util';
 
 
 const Condition: FC<ConditionProps> = props => {
 const Condition: FC<ConditionProps> = props => {
   const {
   const {
@@ -54,9 +22,9 @@ const Condition: FC<ConditionProps> = props => {
     ...others
     ...others
   } = props;
   } = props;
   const [operator, setOperator] = useState(
   const [operator, setOperator] = useState(
-    initData?.op || LogicalOperators[0].value
+    initData?.op || LOGICAL_OPERATORS[0].value
   );
   );
-  const [conditionField, setConditionField] = useState<Field | any>(
+  const [conditionField, setConditionField] = useState<Field>(
     initData?.field || fields[0] || {}
     initData?.field || fields[0] || {}
   );
   );
   const [conditionValue, setConditionValue] = useState(initData?.value || '');
   const [conditionValue, setConditionValue] = useState(initData?.value || '');
@@ -90,6 +58,10 @@ const Condition: FC<ConditionProps> = props => {
           ? regFloatInterval.test(conditionValueWithNoSpace)
           ? regFloatInterval.test(conditionValueWithNoSpace)
           : regFloat.test(conditionValueWithNoSpace);
           : regFloat.test(conditionValueWithNoSpace);
         break;
         break;
+      case 'bool':
+        const legalValues = ['false', 'true'];
+        isLegal = legalValues.includes(conditionValueWithNoSpace);
+        break;
       default:
       default:
         isLegal = false;
         isLegal = false;
         break;
         break;
@@ -108,6 +80,16 @@ const Condition: FC<ConditionProps> = props => {
 
 
   const classes = useStyles();
   const classes = useStyles();
 
 
+  const logicalOperators = useMemo(() => {
+    if (conditionField.type === 'bool') {
+      const data = LOGICAL_OPERATORS.filter(v => v.value === '==');
+      setOperator(data[0].value);
+      // bool only support ==
+      return data;
+    }
+    return LOGICAL_OPERATORS;
+  }, [conditionField]);
+
   // Logic operator input change.
   // Logic operator input change.
   const handleOpChange = (event: React.ChangeEvent<{ value: unknown }>) => {
   const handleOpChange = (event: React.ChangeEvent<{ value: unknown }>) => {
     setOperator(event.target.value);
     setOperator(event.target.value);
@@ -140,7 +122,7 @@ const Condition: FC<ConditionProps> = props => {
         label="Logic"
         label="Logic"
         value={operator}
         value={operator}
         onChange={handleOpChange}
         onChange={handleOpChange}
-        options={LogicalOperators}
+        options={logicalOperators}
         variant="filled"
         variant="filled"
         wrapperClass={classes.logic}
         wrapperClass={classes.logic}
       />
       />

+ 1 - 1
client/src/components/advancedSearch/Types.ts

@@ -12,7 +12,7 @@ export interface ConditionProps {
 
 
 export interface Field {
 export interface Field {
   name: string;
   name: string;
-  type: 'int' | 'float';
+  type: 'int' | 'float' | 'bool';
 }
 }
 
 
 export interface TriggerChangeData {
 export interface TriggerChangeData {

+ 31 - 0
client/src/consts/Util.ts

@@ -4,3 +4,34 @@ export const BYTE_UNITS: { [x: string]: number } = {
   m: 1024 * 1024,
   m: 1024 * 1024,
   g: 1024 * 1024 * 1024,
   g: 1024 * 1024 * 1024,
 };
 };
+
+export const LOGICAL_OPERATORS = [
+  {
+    value: '<',
+    label: '<',
+  },
+  {
+    value: '<=',
+    label: '<=',
+  },
+  {
+    value: '>',
+    label: '>',
+  },
+  {
+    value: '>=',
+    label: '>=',
+  },
+  {
+    value: '==',
+    label: '==',
+  },
+  {
+    value: '!=',
+    label: '!=',
+  },
+  {
+    value: 'in',
+    label: 'in',
+  },
+];

+ 5 - 0
client/src/pages/collections/Constants.ts

@@ -38,6 +38,11 @@ export const ALL_OPTIONS: KeyValuePair[] = [
     label: 'Double',
     label: 'Double',
     value: DataTypeEnum.Double,
     value: DataTypeEnum.Double,
   },
   },
+
+  {
+    label: 'Boolean',
+    value: DataTypeEnum.Bool,
+  },
 ];
 ];
 
 
 export const AUTO_ID_OPTIONS: KeyValuePair[] = [
 export const AUTO_ID_OPTIONS: KeyValuePair[] = [

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

@@ -32,6 +32,7 @@ export interface CollectionCreateParam {
 }
 }
 
 
 export enum DataTypeEnum {
 export enum DataTypeEnum {
+  Bool = 1,
   Int8 = 2,
   Int8 = 2,
   Int16 = 3,
   Int16 = 3,
   Int32 = 4,
   Int32 = 4,
@@ -43,6 +44,7 @@ export enum DataTypeEnum {
 }
 }
 
 
 export type DataType =
 export type DataType =
+  | 'Bool'
   | 'Int8'
   | 'Int8'
   | 'Int16'
   | 'Int16'
   | 'Int32'
   | 'Int32'

+ 18 - 6
client/src/utils/search.ts

@@ -21,11 +21,19 @@ import {
 export const transferSearchResult = (
 export const transferSearchResult = (
   result: SearchResult[]
   result: SearchResult[]
 ): SearchResultView[] => {
 ): SearchResultView[] => {
-  const resultView = result.map((r, index) => ({
-    rank: index + 1,
-    ...r,
-    distance: r.score,
-  }));
+  const resultView = result.map((r, index) => {
+    const { rank, distance, ...others } = r;
+    const data: any = {
+      rank: index + 1,
+      distance: r.score,
+    };
+    // When value is boolean ,table will not render bool value.
+    // So we need to use toString() here.
+    Object.keys(others).forEach(v => {
+      data[v] = others[v].toString();
+    });
+    return data;
+  });
 
 
   return resultView;
   return resultView;
 };
 };
@@ -104,6 +112,10 @@ export const getNonVectorFieldsForFilter = (fields: FieldData[]): Field[] => {
   const intTypes: DataType[] = ['Int8', 'Int16', 'Int32', 'Int64'];
   const intTypes: DataType[] = ['Int8', 'Int16', 'Int32', 'Int64'];
   return fields.map(f => ({
   return fields.map(f => ({
     name: f._fieldName,
     name: f._fieldName,
-    type: intTypes.includes(f._fieldType) ? 'int' : 'float',
+    type: intTypes.includes(f._fieldType)
+      ? 'int'
+      : f._fieldType === 'Bool'
+      ? 'bool'
+      : 'float',
   }));
   }));
 };
 };

+ 5 - 2
server/generate-csv.ts

@@ -3,7 +3,10 @@ import { createObjectCsvWriter as createCsvWriter } from 'csv-writer';
 // use to test vector insert
 // use to test vector insert
 const csvWriter = createCsvWriter({
 const csvWriter = createCsvWriter({
   path: './vectors.csv',
   path: './vectors.csv',
-  header: [{ id: 'vector', title: 'vector' }],
+  header: [
+    { id: 'vector', title: 'vector' },
+    { id: 'bool', title: 'bool' },
+  ],
 });
 });
 
 
 const records = [];
 const records = [];
@@ -20,7 +23,7 @@ const generateVector = (dimension) => {
 
 
 while (records.length < 50000) {
 while (records.length < 50000) {
   const value = generateVector(4);
   const value = generateVector(4);
-  records.push({ vector: value });
+  records.push({ vector: value, bool: records.length % 2 === 0 });
 }
 }
 
 
 csvWriter
 csvWriter