Browse Source

fix wrong copy value for non string and number types (#412)

Signed-off-by: ruiyi.jiang <ruiyi.jiang@zilliz.com>
ryjiang 1 year ago
parent
commit
962451d093

+ 5 - 0
client/src/components/advancedSearch/CopyButton.tsx

@@ -34,6 +34,11 @@ const CopyButton: FC<CopyButtonProps> = props => {
   const handleClick = (event: React.MouseEvent<HTMLElement>, v: string) => {
     event.stopPropagation();
 
+    // for non-string or number value, convert to string
+    if (typeof v !== 'string' || typeof v !== 'number') {
+      v = JSON.stringify(v);
+    }
+
     setTooltipTitle(copyTrans.copied);
     navigator.clipboard?.writeText(v) ?? unsecuredCopyToClipboard(v);
     setTimeout(() => {

+ 13 - 18
client/src/hooks/Query.ts

@@ -1,7 +1,7 @@
 import { useState, useRef, useEffect } from 'react';
-import { DataTypeStringEnum, DYNAMIC_FIELD, MIN_INT64 } from '@/consts';
+import { DataTypeStringEnum, MIN_INT64 } from '@/consts';
 import { CollectionService } from '@/http';
-import { CollectionFullObject } from '@server/types';
+import { CollectionFullObject, FieldObject } from '@server/types';
 
 export const useQuery = (params: {
   onQueryStart: Function;
@@ -11,6 +11,7 @@ export const useQuery = (params: {
 }) => {
   // state
   const [collection, setCollection] = useState<CollectionFullObject>();
+  const [fields, setFields] = useState<FieldObject[]>([]);
   const [consistencyLevel, setConsistencyLevel] = useState<string>('Bounded');
   const [currentPage, setCurrentPage] = useState<number>(0);
   const [pageSize, setPageSize] = useState<number>(0);
@@ -66,7 +67,7 @@ export const useQuery = (params: {
     try {
       const queryParams = {
         expr: _expr,
-        output_fields: collection!.schema.fields.map(i => i.name),
+        output_fields: fields.map(i => i.name),
         limit: pageSize || 10,
         consistency_level,
         // travel_timestamp: timeTravelInfo.timestamp,
@@ -114,21 +115,13 @@ export const useQuery = (params: {
 
   // get collection info
   const prepare = async (collectionName: string) => {
-    const collection = await CollectionService.getCollectionInfo(collectionName);
-    const schemaList = collection.schema.fields;
-
-    const nameList = schemaList.map(v => ({
-      name: v.name,
-      type: v.data_type,
-    }));
-
-    // if the dynamic field is enabled, we add $meta column in the grid
-    if (collection.schema.enable_dynamic_field) {
-      nameList.push({
-        name: DYNAMIC_FIELD,
-        type: DataTypeStringEnum.JSON,
-      });
-    }
+    const collection = await CollectionService.getCollectionInfo(
+      collectionName
+    );
+    setFields([
+      ...collection.schema.fields,
+      ...collection.schema.dynamicFields,
+    ]);
     setConsistencyLevel(collection.consistency_level);
     setCollection(collection);
   };
@@ -198,6 +191,8 @@ export const useQuery = (params: {
   return {
     // collection info(primaryKey, consistency level, fields)
     collection,
+    // fields,
+    fields,
     // total query count
     total,
     // page size

+ 4 - 3
client/src/pages/query/Query.tsx

@@ -106,6 +106,7 @@ const Query = () => {
   // Query hook
   const {
     collection,
+    fields,
     currentPage,
     total,
     pageSize,
@@ -293,7 +294,7 @@ const Query = () => {
                 onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
                   setExpression(e.target.value as string);
                 }}
-                disabled={!collection!.loaded}
+                disabled={!collection.loaded}
                 InputLabelProps={{ shrink: true }}
                 label={collectionTrans('exprPlaceHolder')}
                 onKeyDown={e => {
@@ -366,7 +367,7 @@ const Query = () => {
           </div>
           <AttuGrid
             toolbarConfigs={[]}
-            colDefinitions={collection.schema.fields.map((i: any) => {
+            colDefinitions={fields.map(i => {
               return {
                 id: i.name,
                 align: 'left',
@@ -392,7 +393,7 @@ const Query = () => {
             })}
             primaryKey={collection.schema.primaryField.name}
             openCheckBox={true}
-            isLoading={!!tableLoading}
+            isLoading={tableLoading}
             rows={queryResult.data}
             rowCount={total}
             rowHeight={43}

+ 1 - 5
client/src/pages/search/VectorSearch.tsx

@@ -29,11 +29,7 @@ import SearchParams from './SearchParams';
 import { getVectorSearchStyles } from './Styles';
 import { TOP_K_OPTIONS } from './Constants';
 import { FieldOption, SearchResultView, VectorSearchParam } from './Types';
-import {
-  FieldObject,
-  CollectionObject,
-  CollectionFullObject,
-} from '@server/types';
+import { FieldObject, CollectionFullObject } from '@server/types';
 
 const VectorSearch = () => {
   useNavigationHook(ALL_ROUTER_TYPES.SEARCH);

+ 17 - 0
server/src/collections/collections.service.ts

@@ -31,6 +31,7 @@ import {
   ROW_COUNT,
   convertFieldSchemaToFieldType,
   LOADING_STATE,
+  DYNAMIC_FIELD,
 } from '../utils';
 import { QueryDto, ImportSampleDto, GetReplicasDto } from './dto';
 import {
@@ -122,6 +123,22 @@ export class CollectionsService {
     res.schema.hasVectorIndex = vectorFields.some(v => v.index);
     res.schema.scalarFields = scalarFields;
     res.schema.vectorFields = vectorFields;
+    res.schema.dynamicFields = res.schema.enable_dynamic_field
+      ? [
+          {
+            name: DYNAMIC_FIELD,
+            data_type: 'JSON',
+            type_params: [],
+            index: undefined,
+            description: '',
+            index_params: [],
+            dimension: -1,
+            maxCapacity: -1,
+            maxLength: -1,
+            autoID: false,
+          },
+        ]
+      : [];
 
     return res;
   }

+ 1 - 0
server/src/types/collections.type.ts

@@ -30,6 +30,7 @@ export interface SchemaObject extends CollectionSchema {
   primaryField: FieldObject;
   vectorFields: FieldObject[];
   scalarFields: FieldObject[];
+  dynamicFields: FieldObject[];
   hasVectorIndex: boolean;
 }
 

+ 1 - 0
server/src/utils/Const.ts

@@ -155,3 +155,4 @@ export enum LOADING_STATE {
 }
 
 export const MIN_INT64 = `-9223372036854775807`; // safe int64 min value
+export const DYNAMIC_FIELD = `$meta`;