Skip to content

Commit 8904b54

Browse files
committed
Fix CUD ops inserting vectors without names in >=1.24
1 parent 194f7d0 commit 8904b54

File tree

4 files changed

+145
-36
lines changed

4 files changed

+145
-36
lines changed

.github/workflows/main.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ on:
77
pull_request:
88

99
env:
10-
WEAVIATE_124: 1.24.15
11-
WEAVIATE_125: 1.25.2
10+
WEAVIATE_124: 1.24.19
11+
WEAVIATE_125: 1.25.4
1212

1313
jobs:
1414
checks:

src/collections/data/index.ts

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ const data = <T>(
180180
const objectsPath = new ObjectsPath(dbVersionSupport);
181181
const referencesPath = new ReferencesPath(dbVersionSupport);
182182

183-
const parseObject = (object?: InsertObject<any>): WeaviateObject<T> => {
183+
const parseObject = async (object?: InsertObject<any>): Promise<WeaviateObject<T>> => {
184184
if (!object) {
185185
return {} as WeaviateObject<T>;
186186
}
@@ -191,7 +191,12 @@ const data = <T>(
191191
: undefined,
192192
};
193193
if (Array.isArray(object.vectors)) {
194-
obj.vector = object.vectors;
194+
const supportsNamedVectors = await dbVersionSupport.supportsNamedVectors();
195+
if (supportsNamedVectors.supports) {
196+
obj.vectors = { default: object.vectors };
197+
} else {
198+
obj.vector = object.vectors;
199+
}
195200
} else if (object.vectors) {
196201
obj.vectors = object.vectors;
197202
}
@@ -225,21 +230,24 @@ const data = <T>(
225230
tenant
226231
).do(),
227232
insert: (obj?: InsertObject<T> | NonReferenceInputs<T>): Promise<string> =>
228-
objectsPath
229-
.buildCreate(consistencyLevel)
230-
.then((path) =>
231-
connection.postReturn<WeaviateObject<T>, Required<WeaviateObject<T>>>(path, {
233+
Promise.all([
234+
objectsPath.buildCreate(consistencyLevel),
235+
parseObject(
236+
obj ? (DataGuards.isDataObject(obj) ? obj : ({ properties: obj } as InsertObject<T>)) : obj
237+
),
238+
]).then(([path, object]) =>
239+
connection
240+
.postReturn<WeaviateObject<T>, Required<WeaviateObject<T>>>(path, {
232241
class: name,
233242
tenant: tenant,
234-
...parseObject(
235-
obj ? (DataGuards.isDataObject(obj) ? obj : ({ properties: obj } as InsertObject<T>)) : obj
236-
),
243+
...object,
237244
})
238-
)
239-
.then((obj) => obj.id),
245+
.then((obj) => obj.id)
246+
),
240247
insertMany: (objects: (DataObject<T> | NonReferenceInputs<T>)[]): Promise<BatchObjectsReturn<T>> =>
241248
connection.batch(name, consistencyLevel).then(async (batch) => {
242-
const serialized = await Serialize.batchObjects(name, objects, tenant);
249+
const supportsNamedVectors = await dbVersionSupport.supportsNamedVectors();
250+
const serialized = await Serialize.batchObjects(name, objects, supportsNamedVectors.supports, tenant);
243251
const start = Date.now();
244252
const reply = await batch.withObjects({ objects: serialized.mapped });
245253
const end = Date.now();
@@ -301,20 +309,22 @@ const data = <T>(
301309
.build(args.fromUuid, name, args.fromProperty, consistencyLevel, tenant)
302310
.then((path) => connection.put(path, referenceToBeacons(args.to), false)),
303311
replace: (obj: ReplaceObject<T>): Promise<void> =>
304-
objectsPath.buildUpdate(obj.id, name, consistencyLevel).then((path) =>
305-
connection.put(path, {
306-
class: name,
307-
tenant: tenant,
308-
...parseObject(obj),
309-
})
312+
Promise.all([objectsPath.buildUpdate(obj.id, name, consistencyLevel), parseObject(obj)]).then(
313+
([path, object]) =>
314+
connection.put(path, {
315+
class: name,
316+
tenant: tenant,
317+
...object,
318+
})
310319
),
311320
update: (obj: UpdateObject<T>): Promise<void> =>
312-
objectsPath.buildUpdate(obj.id, name, consistencyLevel).then((path) =>
313-
connection.patch(path, {
314-
class: name,
315-
tenant: tenant,
316-
...parseObject(obj),
317-
})
321+
Promise.all([objectsPath.buildUpdate(obj.id, name, consistencyLevel), parseObject(obj)]).then(
322+
([path, object]) =>
323+
connection.patch(path, {
324+
class: name,
325+
tenant: tenant,
326+
...object,
327+
})
318328
),
319329
};
320330
};

src/collections/data/integration.test.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,3 +914,89 @@ describe('Testing of the collection.data methods with bring your own multi vecto
914914
expect(obj2?.vectors?.two).toEqual([10, 11, 12]);
915915
});
916916
});
917+
918+
describe('Testing of the collection.data methods with a vector index', () => {
919+
let client: WeaviateClient;
920+
let collection: Collection;
921+
let uuid: string;
922+
beforeAll(async () => {
923+
client = await weaviate.connectToLocal();
924+
collection = await client.collections.create({
925+
name: 'TestCollectionDataVectorizer',
926+
properties: [
927+
{
928+
name: 'text',
929+
dataType: 'text',
930+
},
931+
],
932+
vectorizers: weaviate.configure.vectorizer.none(),
933+
});
934+
});
935+
936+
afterAll(() => client.collections.delete('TestCollectionDataVectorizer'));
937+
938+
it('should be able to insert an object with a vector without specifying the name', async () => {
939+
uuid = await collection.data.insert({
940+
properties: {
941+
text: 'test',
942+
},
943+
vectors: [1, 2, 3, 4],
944+
});
945+
const obj = await collection.query.fetchObjectById(uuid, {
946+
includeVector: true,
947+
});
948+
expect(obj?.vectors.default).toEqual([1, 2, 3, 4]);
949+
});
950+
951+
it('should be able to update the vector of an object without specifying the name', async () => {
952+
await collection.data.update({
953+
id: uuid,
954+
vectors: [5, 6, 7, 8],
955+
});
956+
const obj = await collection.query.fetchObjectById(uuid, {
957+
includeVector: true,
958+
});
959+
expect(obj?.vectors.default).toEqual([5, 6, 7, 8]);
960+
});
961+
962+
it('should be able to replace the vector of an object without specifying the name', async () => {
963+
await collection.data.replace({
964+
id: uuid,
965+
vectors: [9, 10, 11, 12],
966+
});
967+
const obj = await collection.query.fetchObjectById(uuid, {
968+
includeVector: true,
969+
});
970+
expect(obj?.vectors.default).toEqual([9, 10, 11, 12]);
971+
});
972+
973+
it('should be able to insert many objects with a vector without specifying the name', async () => {
974+
const objects = [
975+
{
976+
properties: {
977+
text: 'test',
978+
},
979+
vectors: [1, 2, 3, 4],
980+
},
981+
{
982+
properties: {
983+
text: 'test',
984+
},
985+
vectors: [5, 6, 7, 8],
986+
},
987+
];
988+
const insert = await collection.data.insertMany(objects);
989+
expect(insert.hasErrors).toBeFalsy();
990+
expect(insert.allResponses.length).toEqual(2);
991+
expect(Object.values(insert.errors).length).toEqual(0);
992+
expect(Object.values(insert.uuids).length).toEqual(2);
993+
const obj1 = await collection.query.fetchObjectById(insert.uuids[0], {
994+
includeVector: true,
995+
});
996+
expect(obj1?.vectors.default).toEqual([1, 2, 3, 4]);
997+
const obj2 = await collection.query.fetchObjectById(insert.uuids[1], {
998+
includeVector: true,
999+
});
1000+
expect(obj2?.vectors.default).toEqual([5, 6, 7, 8]);
1001+
});
1002+
});

src/collections/serialize/index.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,7 @@ export class Serialize {
10581058
public static batchObjects = <T>(
10591059
collection: string,
10601060
objects: (DataObject<T> | NonReferenceInputs<T>)[],
1061+
usesNamedVectors: boolean,
10611062
tenant?: string
10621063
): Promise<BatchObjects<T>> => {
10631064
const objs: BatchObjectGRPC[] = [];
@@ -1079,22 +1080,34 @@ export class Serialize {
10791080
? object
10801081
: { id: undefined, properties: object, references: undefined, vectors: undefined };
10811082

1083+
let vectorBytes: Uint8Array | undefined;
1084+
let vectors: VectorsGrpc[] | undefined;
1085+
if (obj.vectors !== undefined && !Array.isArray(obj.vectors)) {
1086+
vectors = Object.entries(obj.vectors).map(([k, v]) =>
1087+
VectorsGrpc.fromPartial({
1088+
vectorBytes: Serialize.vectorToBytes(v),
1089+
name: k,
1090+
})
1091+
);
1092+
} else if (Array.isArray(obj.vectors) && usesNamedVectors) {
1093+
vectors = [
1094+
VectorsGrpc.fromPartial({
1095+
vectorBytes: Serialize.vectorToBytes(obj.vectors),
1096+
name: 'default',
1097+
}),
1098+
];
1099+
} else if (obj.vectors !== undefined) {
1100+
vectorBytes = Serialize.vectorToBytes(obj.vectors);
1101+
}
1102+
10821103
objs.push(
10831104
BatchObjectGRPC.fromPartial({
10841105
collection: collection,
10851106
properties: Serialize.batchProperties(obj.properties, obj.references),
10861107
tenant: tenant,
10871108
uuid: obj.id ? obj.id : uuidv4(),
1088-
vectorBytes: Array.isArray(obj.vectors) ? Serialize.vectorToBytes(obj.vectors) : undefined,
1089-
vectors:
1090-
obj.vectors !== undefined && !Array.isArray(obj.vectors)
1091-
? Object.entries(obj.vectors).map(([k, v]) =>
1092-
VectorsGrpc.fromPartial({
1093-
vectorBytes: Serialize.vectorToBytes(v),
1094-
name: k,
1095-
})
1096-
)
1097-
: undefined,
1109+
vectorBytes,
1110+
vectors,
10981111
})
10991112
);
11001113

0 commit comments

Comments
 (0)