Browse Source

feat: Add support for string-type 'vector' field in imported JSON data (#879)

* chore: upgrade node sdk to v2.5.9

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

* feat: Add support for string-type 'vector' field in imported JSON data

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

---------

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

+ 2 - 2
client/src/http/Data.service.ts

@@ -5,7 +5,7 @@ import type {
   DeleteEntitiesReq,
 } from '@/pages/databases/collections/Types';
 import type { VectorSearchParam } from '@/types/SearchTypes';
-import type { VectorSearchResults } from '@server/types';
+import { MutationResult, type VectorSearchResults } from '@server/types';
 
 export class DataService extends BaseModel {
   static importSample(collectionName: string, param: LoadSampleParam) {
@@ -16,7 +16,7 @@ export class DataService extends BaseModel {
   }
 
   static insertData(collectionName: string, param: InsertDataParam) {
-    return super.create({
+    return super.create<MutationResult>({
       path: `/collections/${collectionName}/insert`,
       data: param,
     });

+ 11 - 7
client/src/pages/dialogs/insert/Dialog.tsx

@@ -14,7 +14,7 @@ import DialogTemplate from '@/components/customDialog/DialogTemplate';
 import icons from '@/components/icons/Icons';
 import { PartitionService } from '@/http';
 import { rootContext } from '@/context';
-import { combineHeadsAndData } from '@/utils';
+import { combineHeadsAndData, convertVectorFields } from '@/utils';
 import { FILE_MIME_TYPE } from '@/consts';
 import InsertImport from './Import';
 import InsertPreview from './Preview';
@@ -311,7 +311,7 @@ const InsertContainer: FC<InsertContentProps> = ({
     // process data
     const data =
       typeof jsonData !== 'undefined'
-        ? jsonData
+        ? convertVectorFields(jsonData, fields!)
         : combineHeadsAndData(
             tableHeads,
             isContainFieldNames ? csvData.slice(1) : csvData,
@@ -324,11 +324,15 @@ const InsertContainer: FC<InsertContentProps> = ({
     };
 
     try {
-      await DataService.insertData(collectionValue, param);
-      await DataService.flush(collectionValue);
-      // update collections
-      await onInsert(collectionValue);
-      setInsertStatus(InsertStatusEnum.success);
+      const inserted = await DataService.insertData(collectionValue, param);
+      if (inserted.status.error_code !== 'Success') {
+        setInsertFailMsg(inserted.status.reason);
+      } else {
+        await DataService.flush(collectionValue);
+        // update collections
+        await onInsert(collectionValue);
+        setInsertStatus(InsertStatusEnum.success);
+      }
     } catch (err: any) {
       const {
         response: {

+ 31 - 1
client/src/utils/Format.ts

@@ -1,7 +1,6 @@
 import {
   BYTE_UNITS,
   DEFAULT_MILVUS_PORT,
-  DEFAULT_PROMETHEUS_PORT,
   VectorTypes,
   DataTypeStringEnum,
   DEFAULT_ANALYZER_PARAMS,
@@ -403,3 +402,34 @@ export const parseCollectionJson = (json: any) => {
 
   return { form, fields, consistencyLevel, properties };
 };
+
+export const convertVectorFields = (
+  jsonData: Record<string, any> | Record<string, any>[],
+  fields: any[]
+): typeof jsonData => {
+  const vectorFields = fields.filter(isVectorType).map(f => f.name);
+
+  const convert = (item: Record<string, any>) => {
+    const newItem = { ...item };
+    vectorFields.forEach(field => {
+      if (typeof newItem[field] === 'string') {
+        try {
+          const str = newItem[field].trim();
+          if (str.startsWith('[') && str.endsWith(']')) {
+            newItem[field] = JSON.parse(str);
+          } else {
+            newItem[field] = str.split(',').map(Number);
+          }
+        } catch {
+          // If parsing fails, keep the original string
+        }
+      }
+    });
+    return newItem;
+  };
+
+  if (Array.isArray(jsonData)) {
+    return jsonData.map(convert);
+  }
+  return convert(jsonData);
+};

+ 1 - 0
server/src/types/index.ts

@@ -8,6 +8,7 @@ export {
   TypeParam,
   QueryResults,
   SearchResultData,
+  MutationResult,
 } from '@zilliz/milvus2-sdk-node';
 
 export * from './collections.type';