From 0c0cee0b2f195c8b1a0eec934a1ca1966ffb88cb Mon Sep 17 00:00:00 2001 From: shanghaikid Date: Mon, 28 Aug 2023 19:08:59 +0800 Subject: [PATCH 1/4] support cosine and scann Signed-off-by: shanghaikid --- client/src/consts/Milvus.ts | 14 ++++++++++++++ client/src/pages/search/SearchParams.tsx | 2 ++ client/src/pages/search/VectorSearch.tsx | 15 +-------------- client/src/utils/Form.ts | 4 ++++ 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/client/src/consts/Milvus.ts b/client/src/consts/Milvus.ts index 2cfcac14..5fe2eb25 100644 --- a/client/src/consts/Milvus.ts +++ b/client/src/consts/Milvus.ts @@ -6,6 +6,7 @@ export const MILVUS_URL = export enum METRIC_TYPES_VALUES { L2 = 'L2', IP = 'IP', + COSINE = 'COSINE', HAMMING = 'HAMMING', JACCARD = 'JACCARD', TANIMOTO = 'TANIMOTO', @@ -22,6 +23,10 @@ export const METRIC_TYPES = [ value: METRIC_TYPES_VALUES.IP, label: 'IP', }, + { + value: METRIC_TYPES_VALUES.COSINE, + label: 'COSINE', + }, { value: METRIC_TYPES_VALUES.SUBSTRUCTURE, label: 'SUBSTRUCTURE', @@ -47,6 +52,7 @@ export const METRIC_TYPES = [ export type MetricType = | 'L2' | 'IP' + | 'COSINE' | 'HAMMING' | 'SUBSTRUCTURE' | 'SUPERSTRUCTURE' @@ -71,6 +77,10 @@ export type indexConfigType = { // index export const FLOAT_INDEX_CONFIG: indexConfigType = { + SCANN: { + create: ['nlist'], + search: ['nprobe'], + }, IVF_FLAT: { create: ['nlist'], search: ['nprobe'], @@ -159,6 +169,10 @@ export const METRIC_OPTIONS_MAP = { value: METRIC_TYPES_VALUES.IP, label: METRIC_TYPES_VALUES.IP, }, + { + value: METRIC_TYPES_VALUES.COSINE, + label: METRIC_TYPES_VALUES.COSINE, + }, ], [DataTypeEnum.BinaryVector]: [ { diff --git a/client/src/pages/search/SearchParams.tsx b/client/src/pages/search/SearchParams.tsx index 7f76be22..9f19f157 100644 --- a/client/src/pages/search/SearchParams.tsx +++ b/client/src/pages/search/SearchParams.tsx @@ -20,6 +20,7 @@ import { SearchParamInputConfig, SearchParamsProps } from './Types'; const getStyles = makeStyles((theme: Theme) => ({ selector: { width: '100%', + display: 'none', marginBottom: theme.spacing(2), }, input: { @@ -294,6 +295,7 @@ const SearchParams: FC = ({ label={indexTrans('metric')} wrapperClass={classes.selector} variant="filled" + disabled={true} onChange={(e: { target: { value: unknown } }) => { const metricType = e.target.value as string; handleMetricTypeChange(metricType); diff --git a/client/src/pages/search/VectorSearch.tsx b/client/src/pages/search/VectorSearch.tsx index 19d2a968..d71c842f 100644 --- a/client/src/pages/search/VectorSearch.tsx +++ b/client/src/pages/search/VectorSearch.tsx @@ -1,11 +1,5 @@ import { useCallback, useEffect, useMemo, useState, useContext } from 'react'; -import { - Typography, - Button, - Card, - CardContent, - CardActionArea, -} from '@material-ui/core'; +import { Typography, Button, Card, CardContent } from '@material-ui/core'; import { useTranslation } from 'react-i18next'; import { useLocation } from 'react-router-dom'; import { ALL_ROUTER_TYPES } from '@/router/Types'; @@ -26,7 +20,6 @@ import SimpleMenu from '@/components/menu/SimpleMenu'; import { Option } from '@/components/customSelector/Types'; import Filter from '@/components/advancedSearch'; import { Field } from '@/components/advancedSearch/Types'; -import { CustomDatePicker } from '@/components/customDatePicker/CustomDatePicker'; import { CollectionHttp, IndexHttp } from '@/http'; import { parseValue, @@ -514,12 +507,6 @@ const VectorSearch = () => { filterDisabled={selectedField === '' || selectedCollection === ''} onSubmit={handleAdvancedFilterChange} /> -
diff --git a/client/src/utils/Form.ts b/client/src/utils/Form.ts index 59a72a8e..2afae28c 100644 --- a/client/src/utils/Form.ts +++ b/client/src/utils/Form.ts @@ -33,6 +33,10 @@ export const getMetricOptions = ( value: METRIC_TYPES_VALUES.IP, label: 'IP', }, + { + value: METRIC_TYPES_VALUES.COSINE, + label: 'COSINE', + }, ]; const baseBinaryOptions = [ From ee15ff730a7561f1d570f3274d0cf43b63420fee Mon Sep 17 00:00:00 2001 From: "ruiyi.jiang" Date: Mon, 28 Aug 2023 21:09:31 +0800 Subject: [PATCH 2/4] show metric type Signed-off-by: ruiyi.jiang --- client/src/pages/search/SearchParams.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/pages/search/SearchParams.tsx b/client/src/pages/search/SearchParams.tsx index 9f19f157..d95bb39f 100644 --- a/client/src/pages/search/SearchParams.tsx +++ b/client/src/pages/search/SearchParams.tsx @@ -20,7 +20,6 @@ import { SearchParamInputConfig, SearchParamsProps } from './Types'; const getStyles = makeStyles((theme: Theme) => ({ selector: { width: '100%', - display: 'none', marginBottom: theme.spacing(2), }, input: { From 82182c4ddd2d7d19bcf32f9282e5014ce9968722 Mon Sep 17 00:00:00 2001 From: "ruiyi.jiang" Date: Mon, 28 Aug 2023 21:38:39 +0800 Subject: [PATCH 3/4] ragne filter part1 Signed-off-by: ruiyi.jiang --- client/src/consts/Milvus.ts | 6 +++- client/src/pages/search/SearchParams.tsx | 36 ++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/client/src/consts/Milvus.ts b/client/src/consts/Milvus.ts index 5fe2eb25..84699205 100644 --- a/client/src/consts/Milvus.ts +++ b/client/src/consts/Milvus.ts @@ -66,7 +66,9 @@ export type searchKeywordsType = | 'search_length' | 'round_decimal' | 'level' - | 'search_list'; + | 'search_list' + | 'range' + | 'range_filter'; export type indexConfigType = { [x: string]: { @@ -222,6 +224,8 @@ export const DEFAULT_SEARCH_PARAM_VALUE_MAP: { round_decimal: -1, level: 1, search_list: 20, + range: 20, + range_filter: 10 }; export const DEFAULT_NLIST_VALUE = 1024; diff --git a/client/src/pages/search/SearchParams.tsx b/client/src/pages/search/SearchParams.tsx index d95bb39f..fcce8716 100644 --- a/client/src/pages/search/SearchParams.tsx +++ b/client/src/pages/search/SearchParams.tsx @@ -66,9 +66,15 @@ const SearchParams: FC = ({ 'warning' ); } + + const commonParams: searchKeywordsType[] = [ + 'range', + 'range_filter', + 'round_decimal', + ]; return indexType !== '' && isSupportedType - ? [...INDEX_CONFIG[indexType].search, 'round_decimal'] - : ['round_decimal']; + ? [...INDEX_CONFIG[indexType].search, ...commonParams] + : commonParams; }, [indexType, openSnackBar, warningTrans]); const handleInputChange = useCallback( @@ -168,7 +174,7 @@ const SearchParams: FC = ({ [key in searchKeywordsType]: SearchParamInputConfig; } = { round_decimal: { - label: 'Round Decimals', + label: 'Round', key: 'round_decimal', value: searchParamsForm['round_decimal'] || '', min: -1, @@ -191,6 +197,30 @@ const SearchParams: FC = ({ }, className: classes.inlineInput, }, + range: { + label: 'range', + key: 'range', + value: searchParamsForm['range'] || '', + min: 1, + max: 500, + isInt: false, + handleChange: value => { + handleInputChange('range', Number(value)); + }, + className: classes.inlineInput, + }, + range_filter: { + label: 'range_filter', + key: 'range_filter', + value: searchParamsForm['range_filter'] || '', + min: 1, + max: 500, + isInt: false, + handleChange: value => { + handleInputChange('range_filter', Number(value)); + }, + className: classes.inlineInput, + }, ef: { label: 'ef', key: 'ef', From 5cd4f5cfff343faa452962858836b2b0bd22df30 Mon Sep 17 00:00:00 2001 From: shanghaikid Date: Tue, 29 Aug 2023 16:35:49 +0800 Subject: [PATCH 4/4] fix range search Signed-off-by: shanghaikid --- .../customSnackBar/CustomSnackBar.tsx | 5 +- client/src/consts/Milvus.ts | 7 +- client/src/context/Root.tsx | 2 +- client/src/pages/search/SearchParams.tsx | 69 ++++++++++--------- client/src/pages/search/Types.ts | 1 + client/src/pages/search/VectorSearch.tsx | 12 +--- 6 files changed, 43 insertions(+), 53 deletions(-) diff --git a/client/src/components/customSnackBar/CustomSnackBar.tsx b/client/src/components/customSnackBar/CustomSnackBar.tsx index 3eca3d47..e2ff8e8e 100644 --- a/client/src/components/customSnackBar/CustomSnackBar.tsx +++ b/client/src/components/customSnackBar/CustomSnackBar.tsx @@ -19,7 +19,8 @@ const useStyles = makeStyles((theme: Theme) => createStyles({ root: { borderRadius: '4px', - maxWidth: '300px', + maxWidth: '50vh', + wordBreak: 'break-all' }, topRight: { [theme.breakpoints.up('md')]: { @@ -37,7 +38,7 @@ const CustomSnackBar: FC = props => { vertical, horizontal, open, - autoHideDuration = 2000, + autoHideDuration = 2500, type, message, onClose, diff --git a/client/src/consts/Milvus.ts b/client/src/consts/Milvus.ts index 84699205..0c6fdec7 100644 --- a/client/src/consts/Milvus.ts +++ b/client/src/consts/Milvus.ts @@ -67,7 +67,7 @@ export type searchKeywordsType = | 'round_decimal' | 'level' | 'search_list' - | 'range' + | 'radius' | 'range_filter'; export type indexConfigType = { @@ -211,7 +211,7 @@ export const DEFAULT_METRIC_VALUE_MAP = { // search params default value map export const DEFAULT_SEARCH_PARAM_VALUE_MAP: { - [key in searchKeywordsType]: number; + [key in searchKeywordsType]?: number; } = { // range: [top_k, 32768] ef: 250, @@ -221,11 +221,8 @@ export const DEFAULT_SEARCH_PARAM_VALUE_MAP: { search_k: 250, // range: [10, 300] search_length: 10, - round_decimal: -1, level: 1, search_list: 20, - range: 20, - range_filter: 10 }; export const DEFAULT_NLIST_VALUE = 1024; diff --git a/client/src/context/Root.tsx b/client/src/context/Root.tsx index 3763b84d..bb94406a 100644 --- a/client/src/context/Root.tsx +++ b/client/src/context/Root.tsx @@ -61,7 +61,7 @@ export const RootProvider = (props: { children: React.ReactNode }) => { message: '', vertical: 'top', horizontal: 'right', - autoHideDuration: 3000, + autoHideDuration: 1000, }); const [dialog, setDialog] = useState(DefaultDialogConfigs); const [drawer, setDrawer]: any = useState({ diff --git a/client/src/pages/search/SearchParams.tsx b/client/src/pages/search/SearchParams.tsx index fcce8716..79732170 100644 --- a/client/src/pages/search/SearchParams.tsx +++ b/client/src/pages/search/SearchParams.tsx @@ -68,7 +68,7 @@ const SearchParams: FC = ({ } const commonParams: searchKeywordsType[] = [ - 'range', + 'radius', 'range_filter', 'round_decimal', ]; @@ -78,8 +78,14 @@ const SearchParams: FC = ({ }, [indexType, openSnackBar, warningTrans]); const handleInputChange = useCallback( - (key: string, value: number) => { - const form = { ...searchParamsForm, [key]: value }; + (key: string, value: number | string) => { + let form = { ...searchParamsForm }; + if (value === '') { + delete form[key]; + } else { + form = { ...searchParamsForm, [key]: Number(value) }; + } + handleFormChange(form); }, [handleFormChange, searchParamsForm] @@ -98,6 +104,7 @@ const SearchParams: FC = ({ value, handleChange, isInt = true, + required = true, } = params; // search_k range is special compared to others,need to be handled separately @@ -114,22 +121,13 @@ const SearchParams: FC = ({ variant: 'filled', type: 'number', value, - validations: [ - { - rule: 'require', - errorText: warningTrans('required', { name: label }), - }, - ], + validations: [], }; - if (!isSearchK && min && max) { + + if (required) { config.validations?.push({ - rule: 'range', - errorText: warningTrans('range', { min, max }), - extraParam: { - min, - max, - type: 'number', - }, + rule: 'require', + errorText: warningTrans('required', { name: label }), }); } @@ -174,14 +172,15 @@ const SearchParams: FC = ({ [key in searchKeywordsType]: SearchParamInputConfig; } = { round_decimal: { - label: 'Round', + label: 'round', key: 'round_decimal', value: searchParamsForm['round_decimal'] || '', min: -1, max: 10, isInt: true, + required: false, handleChange: value => { - handleInputChange('round_decimal', Number(value)); + handleInputChange('round_decimal', value); }, className: classes.inlineInput, }, @@ -193,31 +192,33 @@ const SearchParams: FC = ({ max: nlist, isInt: true, handleChange: value => { - handleInputChange('nprobe', Number(value)); + handleInputChange('nprobe', value); }, className: classes.inlineInput, }, - range: { - label: 'range', - key: 'range', - value: searchParamsForm['range'] || '', + radius: { + label: 'radius', + key: 'radius', + value: searchParamsForm['radius'] || '', min: 1, - max: 500, + max: 1024, isInt: false, + required: false, handleChange: value => { - handleInputChange('range', Number(value)); + handleInputChange('radius', value); }, className: classes.inlineInput, }, range_filter: { - label: 'range_filter', + label: 'range filter', key: 'range_filter', value: searchParamsForm['range_filter'] || '', min: 1, - max: 500, + max: 1024, isInt: false, + required: false, handleChange: value => { - handleInputChange('range_filter', Number(value)); + handleInputChange('range_filter', value); }, className: classes.inlineInput, }, @@ -229,7 +230,7 @@ const SearchParams: FC = ({ max: 32768, isInt: true, handleChange: value => { - handleInputChange('ef', Number(value)); + handleInputChange('ef', value); }, }, level: { @@ -240,7 +241,7 @@ const SearchParams: FC = ({ max: 3, isInt: true, handleChange: value => { - handleInputChange('level', Number(value)); + handleInputChange('level', value); }, }, search_k: { @@ -252,7 +253,7 @@ const SearchParams: FC = ({ max: Infinity, isInt: true, handleChange: value => { - handleInputChange('search_k', Number(value)); + handleInputChange('search_k', value); }, }, search_length: { @@ -263,7 +264,7 @@ const SearchParams: FC = ({ max: 300, isInt: true, handleChange: value => { - handleInputChange('search_length', Number(value)); + handleInputChange('search_length', value); }, }, search_list: { @@ -274,7 +275,7 @@ const SearchParams: FC = ({ max: 65535, isInt: true, handleChange: value => { - handleInputChange('search_list', Number(value)); + handleInputChange('search_list', value); }, }, }; diff --git a/client/src/pages/search/Types.ts b/client/src/pages/search/Types.ts index 6636e611..4844473f 100644 --- a/client/src/pages/search/Types.ts +++ b/client/src/pages/search/Types.ts @@ -52,6 +52,7 @@ export interface SearchParamInputConfig { value: number | string; handleChange: (value: number) => void; className?: string; + required?: boolean; } export interface VectorSearchParam { diff --git a/client/src/pages/search/VectorSearch.tsx b/client/src/pages/search/VectorSearch.tsx index d71c842f..56ad33d9 100644 --- a/client/src/pages/search/VectorSearch.tsx +++ b/client/src/pages/search/VectorSearch.tsx @@ -3,12 +3,7 @@ import { Typography, Button, Card, CardContent } from '@material-ui/core'; import { useTranslation } from 'react-i18next'; import { useLocation } from 'react-router-dom'; import { ALL_ROUTER_TYPES } from '@/router/Types'; -import { - useNavigationHook, - useSearchResult, - usePaginationHook, - useTimeTravelHook, -} from '@/hooks'; +import { useNavigationHook, useSearchResult, usePaginationHook } from '@/hooks'; import { dataContext } from '@/context'; import CustomSelector from '@/components/customSelector/CustomSelector'; import { ColDefinitionsType } from '@/components/grid/Types'; @@ -92,9 +87,6 @@ const VectorSearch = () => { handleGridSort, } = usePaginationHook(searchResultMemo || []); - const { timeTravel, setTimeTravel, timeTravelInfo, handleDateTimeChange } = - useTimeTravelHook(); - const collectionOptions: Option[] = useMemo( () => collections.map(c => ({ @@ -317,7 +309,6 @@ const VectorSearch = () => { setSearchResult(null); setFilterFields([]); setExpression(''); - setTimeTravel(null); }; const handleSearch = async (topK: number, expr = expression) => { @@ -337,7 +328,6 @@ const VectorSearch = () => { search_params: searchParamPairs, vectors: [parseValue(vectors)], vector_type: fieldType, - travel_timestamp: timeTravelInfo.timestamp, }; setTableLoading(true);