Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix upsert failed on autoid enabled collection #402

Merged
merged 2 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions milvus/grpc/Data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,16 @@ export class Data extends Collection {
}

// Tip: The field data sequence needs to be set same as `collectionInfo.schema.fields`.
// If primarykey is set `autoid = true`, you cannot insert the data.
// and if function field is set, you need to ignore the field value in the data.
const functionOutputFields: string[] = [];
const fieldMap = new Map<string, _Field>(
collectionInfo.schema.fields.reduce((acc, v) => {
// if autoID is true, ignore the primary key field or if upsert is true
const insertable = !v.autoID || upsert;

// if function field is set, you need to ignore the field value in the data.
if (v.is_function_output) {
functionOutputFields.push(v.name); // ignore function field
} else if (!v.is_primary_key || !v.autoID) {
} else if (insertable) {
acc.push([
v.name,
{
Expand Down
71 changes: 65 additions & 6 deletions test/grpc/Upsert.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
genCollectionParams,
VECTOR_FIELD_NAME,
GENERATE_NAME,
dynamicFields,
} from '../tools';

const milvusClient = new MilvusClient({ address: IP });
Expand All @@ -29,6 +30,14 @@ const COLLECTION_NAME_AUTO_ID_PARAMS = genCollectionParams({
dim: [4],
vectorType: [DataType.FloatVector],
autoID: true,
enableDynamic: true,
fields: [
{
name: 'other_ids',
data_type: DataType.Int32,
description: '',
},
],
});

const PARTITION_NAME = 'test';
Expand Down Expand Up @@ -56,6 +65,30 @@ describe(`Upsert API`, () => {

// create collection autoid = true and float_vector
await milvusClient.createCollection(COLLECTION_NAME_AUTO_ID_PARAMS);
// create index before load
await milvusClient.createIndex({
collection_name: COLLECTION_NAME_AUTO_ID,
field_name: VECTOR_FIELD_NAME,
extra_params: {
index_type: 'IVF_FLAT',
metric_type: 'L2',
params: JSON.stringify({ nlist: 1024 }),
},
});
// load collection
await milvusClient.loadCollectionSync({
collection_name: COLLECTION_NAME_AUTO_ID,
});
// pare data
const vectorsData = generateInsertData(
[...COLLECTION_NAME_AUTO_ID_PARAMS.fields, ...dynamicFields],
10
);
// insert data
await milvusClient.insert({
collection_name: COLLECTION_NAME_AUTO_ID,
fields_data: vectorsData,
});

// create collection autoid = false and binary_vector

Expand Down Expand Up @@ -162,20 +195,46 @@ describe(`Upsert API`, () => {
}
});

it(`Upsert Data on float field and autoId is true expect error`, async () => {
const vectorsData = generateInsertData(
COLLECTION_NAME_AUTO_ID_PARAMS.fields,
10
);
it(`Upsert Data on float field and autoId is true expect successful`, async () => {
const query = await milvusClient.query({
collection_name: COLLECTION_NAME_AUTO_ID,
expr: 'id > 0',
limit: 4,
});

const other_ids = query.data.map((item: any) => item.other_ids);

// modify the bool field to true
const vectorsData = query.data.map((item: any) => {
item.bool = true;
item.dynamic_upserted_int32 = 100;
return item;
});

// upsert the data
const params: InsertReq = {
collection_name: COLLECTION_NAME_AUTO_ID,
fields_data: vectorsData,
};

// expect successful
const res = await milvusClient.upsert(params);
expect(res.status.error_code).toEqual(ErrorCode.SUCCESS);

expect(res.status.error_code).toEqual(ErrorCode.IllegalArgument);
// query these id
const query2 = await milvusClient.query({
collection_name: COLLECTION_NAME_AUTO_ID,
expr: `other_ids in [${other_ids.join(',')}]`,
limit: 4,
});
// check the bool field
expect(query2.data.every((item: any) => item.bool)).toBeTruthy();
// check the dynamic field
expect(
query2.data.every(
(item: any) => item.$meta.dynamic_upserted_int32 === 100
)
).toBeTruthy();
});

it(`Upsert Data on different scalar fields`, async () => {
Expand Down
Loading