Browse Source

support custom filter expression on search page (#462)

* support custom filter expression on search page

Signed-off-by: ryjiang <jiangruiyi@gmail.com>

* fix adv filter

Signed-off-by: ryjiang <jiangruiyi@gmail.com>

---------

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

+ 1 - 1
client/src/components/advancedSearch/Filter.tsx

@@ -90,7 +90,7 @@ const Filter = forwardRef((props: FilterProps, ref) => {
       let n = name;
 
       // if type is json, format json expression
-      if (data.field.type === 'JSON') {
+      if (data.field.data_type === 'JSON') {
         n = `${name}["${jsonKey}"]`;
       }
 

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

@@ -18,6 +18,8 @@ const searchTrans = {
   collectionNotLoaded: 'Collection 没有加载',
   advancedFilter: '高级过滤',
   addCondition: '添加条件',
+  filterExpr: '过滤表达式',
+  exprHelper: '表达式助手',
 };
 
 export default searchTrans;

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

@@ -18,6 +18,8 @@ const searchTrans = {
   collectionNotLoaded: 'Please load the collection first.',
   advancedFilter: 'Advanced Filter',
   addCondition: 'Add Condition',
+  filterExpr: 'Filter expression, eg: id > 0 ',
+  exprHelper: 'Expr Helper',
 };
 
 export default searchTrans;

+ 0 - 6
client/src/pages/databases/collections/data/CollectionData.tsx

@@ -320,12 +320,6 @@ const CollectionData = (props: CollectionDataProps) => {
             <div className="left">
               <TextField
                 className="textarea"
-                InputProps={{
-                  classes: {
-                    root: 'textfield',
-                    multiline: 'multiline',
-                  },
-                }}
                 value={expression}
                 onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
                   setExpression(e.target.value as string);

+ 0 - 7
client/src/pages/databases/collections/data/Styles.ts

@@ -37,13 +37,6 @@ export const getQueryStyles = makeStyles((theme: Theme) => ({
       },
       '& .textarea': {
         width: '100%',
-        '& .MuiInput-underline:before': {
-          borderWidth: 1,
-          borderColor: '#f4f4f4',
-        },
-        '& .MuiInput-underline:after': {
-          borderWidth: 1,
-        },
       },
     },
 

+ 19 - 9
client/src/pages/search/Styles.ts

@@ -67,28 +67,28 @@ export const getVectorSearchStyles = makeStyles((theme: Theme) => ({
     flexDirection: 'column',
     flexGrow: 0,
     width: `calc(100% - 396px)`,
-    padding: theme.spacing(1, 2),
+    padding: theme.spacing(1),
   },
   toolbar: {
     display: 'flex',
     justifyContent: 'space-between',
     alignItems: 'center',
+    background: '#fff',
+    paddingBottom: theme.spacing(1),
+    '& .icon': {
+      fontSize: '16px',
+    },
 
     '& .left': {
       display: 'flex',
       alignItems: 'center',
 
-      '& .text': {
-      },
-    },
-    '& .right': {
-      '& .btn': {
+      '& .text': { fontSize: 12, minWidth: '92px' },
+      '& .MuiButton-root': {
         marginRight: theme.spacing(1),
       },
-      '& .icon': {
-        fontSize: '16px',
-      },
     },
+    '& .right': {},
   },
   menuLabel: {
     minWidth: '108px',
@@ -116,4 +116,14 @@ export const getVectorSearchStyles = makeStyles((theme: Theme) => ({
     display: 'flex',
     whiteSpace: 'nowrap',
   },
+
+  filterExpressionInput: {
+    width: '33vw',
+    '& .MuiInput-underline:before': {
+      borderWidth: 1,
+    },
+    '& .MuiInput-underline:after': {
+      borderWidth: 1,
+    },
+  },
 }));

+ 22 - 3
client/src/pages/search/VectorSearch.tsx

@@ -1,5 +1,5 @@
 import { useCallback, useEffect, useMemo, useState, useContext } from 'react';
-import { Typography, CardContent } from '@material-ui/core';
+import { Typography, CardContent, TextField } from '@material-ui/core';
 import { useTranslation } from 'react-i18next';
 import { useLocation } from 'react-router-dom';
 import { ALL_ROUTER_TYPES } from '@/router/Types';
@@ -247,7 +247,7 @@ const VectorSearch = () => {
         setSelectedField(defaultFieldValue as string);
       }
 
-      if(col?.schema) {
+      if (col?.schema) {
         setFilterFields(col?.schema.scalarFields!);
       }
     },
@@ -425,6 +425,7 @@ const VectorSearch = () => {
               })}
             </Typography>
           )}
+
           {selectedFieldDimension !== 0 ? (
             <CustomButton
               className={classes.exampleBtn}
@@ -498,11 +499,29 @@ const VectorSearch = () => {
               menuItemWidth="108px"
             />
 
+            <TextField
+              className={classes.filterExpressionInput}
+              value={expression}
+              onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
+                setExpression(e.target.value as string);
+              }}
+              disabled={selectedField === '' || selectedCollection === ''}
+              InputLabelProps={{ shrink: true }}
+              placeholder={searchTrans('filterExpr')}
+              onKeyDown={e => {
+                if (e.key === 'Enter') {
+                  handleAdvancedFilterChange(expression);
+                  e.preventDefault();
+                }
+              }}
+            />
+
             <Filter
-              title="Advanced Filter"
+              title={searchTrans('exprHelper')}
               fields={filterFields}
               filterDisabled={selectedField === '' || selectedCollection === ''}
               onSubmit={handleAdvancedFilterChange}
+              showTooltip={false}
             />
             <CustomButton
               className="btn"

+ 10 - 0
client/src/styles/theme.ts

@@ -197,6 +197,16 @@ export const theme = createMuiTheme({
       },
     },
 
+    MuiInput: {
+      underline: {
+        '&:hover:not(.Mui-disabled):before': {
+          borderWidth: 1,
+        },
+        borderWidth: 1,
+        borderColor: 'transparent',
+      },
+    },
+
     // Date time picker theme overrides
     MuiPickersToolbar: {
       toolbar: {