Skip to content

Commit ee4bd63

Browse files
committed
Fix parsing of files and buffers in nearMedia methods
1 parent 6beaf05 commit ee4bd63

File tree

8 files changed

+225
-178
lines changed

8 files changed

+225
-178
lines changed

ci/docker-compose.yml

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,43 @@
22
version: '3.4'
33
services:
44
weaviate:
5+
command:
6+
- --host
7+
- 0.0.0.0
8+
- --port
9+
- '8080'
10+
- --scheme
11+
- http
12+
- --write-timeout=600s
513
image: semitechnologies/weaviate:${WEAVIATE_VERSION}
6-
restart: on-failure:0
714
ports:
815
- "8080:8080"
916
- "50051:50051"
17+
restart: on-failure:0
1018
environment:
1119
CONTEXTIONARY_URL: contextionary:9999
12-
QUERY_DEFAULTS_LIMIT: 20
20+
QUERY_DEFAULTS_LIMIT: 25
1321
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
14-
PERSISTENCE_DATA_PATH: "./weaviate-data"
15-
DEFAULT_VECTORIZER_MODULE: text2vec-contextionary
16-
ENABLE_MODULES: text2vec-contextionary,backup-filesystem
22+
PERSISTENCE_DATA_PATH: '/var/lib/weaviate'
23+
DEFAULT_VECTORIZER_MODULE: 'text2vec-contextionary'
24+
ENABLE_MODULES: text2vec-contextionary,backup-filesystem,img2vec-neural
1725
BACKUP_FILESYSTEM_PATH: "/tmp/backups"
1826
CLUSTER_GOSSIP_BIND_PORT: "7100"
1927
CLUSTER_DATA_BIND_PORT: "7101"
20-
DISABLE_TELEMETRY: 'true'
28+
CLUSTER_HOSTNAME: "node1"
2129
AUTOSCHEMA_ENABLED: 'false'
30+
IMAGE_INFERENCE_API: "http://i2v-neural:8080"
31+
DISABLE_TELEMETRY: 'true'
2232
contextionary:
23-
image: semitechnologies/contextionary:en0.16.0-v1.2.1
24-
ports:
25-
- "9999:9999"
2633
environment:
2734
OCCURRENCE_WEIGHT_LINEAR_FACTOR: 0.75
2835
EXTENSIONS_STORAGE_MODE: weaviate
2936
EXTENSIONS_STORAGE_ORIGIN: http://weaviate:8080
3037
NEIGHBOR_OCCURRENCE_IGNORE_PERCENTILE: 5
3138
ENABLE_COMPOUND_SPLITTING: 'false'
39+
image: semitechnologies/contextionary:en0.16.0-v1.2.0
40+
ports:
41+
- 9999:9999
42+
i2v-neural:
43+
image: semitechnologies/img2vec-pytorch:resnet50
3244
...

src/collections/aggregate/index.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { FilterValue } from '../filters/index.js';
77

88
import { WeaviateQueryError } from '../../errors.js';
99
import { Aggregator } from '../../graphql/index.js';
10+
import { toBase64FromMedia } from '../../index.js';
1011
import { Serialize } from '../serialize/index.js';
1112

1213
export type AggregateBaseOptions<T, M> = {
@@ -345,12 +346,12 @@ class AggregateManager<T> implements Aggregate<T> {
345346
this.tenant = tenant;
346347

347348
this.groupBy = {
348-
nearImage: <M extends PropertiesMetrics<T> | undefined = undefined>(
349-
image: string,
349+
nearImage: async <M extends PropertiesMetrics<T> | undefined = undefined>(
350+
image: string | Buffer,
350351
opts?: AggregateGroupByNearOptions<T, M>
351352
): Promise<AggregateGroupByResult<T, M>[]> => {
352353
const builder = this.base(opts?.returnMetrics, opts?.filters, opts?.groupBy).withNearImage({
353-
image: image,
354+
image: await toBase64FromMedia(image),
354355
certainty: opts?.certainty,
355356
distance: opts?.distance,
356357
targetVectors: opts?.targetVector ? [opts.targetVector] : undefined,
@@ -488,12 +489,12 @@ class AggregateManager<T> implements Aggregate<T> {
488489
return new AggregateManager<T>(connection, name, dbVersionSupport, consistencyLevel, tenant);
489490
}
490491

491-
nearImage<M extends PropertiesMetrics<T>>(
492-
image: string,
492+
async nearImage<M extends PropertiesMetrics<T>>(
493+
image: string | Buffer,
493494
opts?: AggregateNearOptions<T, M>
494495
): Promise<AggregateResult<T, M>> {
495496
const builder = this.base(opts?.returnMetrics, opts?.filters).withNearImage({
496-
image: image,
497+
image: await toBase64FromMedia(image),
497498
certainty: opts?.certainty,
498499
distance: opts?.distance,
499500
targetVectors: opts?.targetVector ? [opts.targetVector] : undefined,
@@ -608,12 +609,12 @@ export interface Aggregate<T> {
608609
*
609610
* This method requires a vectorizer capable of handling base64-encoded images, e.g. `img2vec-neural`, `multi2vec-clip`, and `multi2vec-bind`.
610611
*
611-
* @param {string} image The base64-encoded image to search for.
612+
* @param {string | Buffer} image The image to search on. This can be a base64 string, a file path string, or a buffer.
612613
* @param {AggregateNearOptions<T, M>} [opts] The options for the request.
613614
* @returns {Promise<AggregateResult<T, M>[]>} The aggregated metrics for the objects returned by the vector search.
614615
*/
615616
nearImage<M extends PropertiesMetrics<T>>(
616-
image: string,
617+
image: string | Buffer,
617618
opts?: AggregateNearOptions<T, M>
618619
): Promise<AggregateResult<T, M>>;
619620
/**
@@ -678,12 +679,12 @@ export interface AggregateGroupBy<T> {
678679
*
679680
* This method requires a vectorizer capable of handling base64-encoded images, e.g. `img2vec-neural`, `multi2vec-clip`, and `multi2vec-bind`.
680681
*
681-
* @param {string} image The base64-encoded image to search for.
682+
* @param {string | Buffer} image The image to search on. This can be a base64 string, a file path string, or a buffer.
682683
* @param {AggregateGroupByNearOptions<T, M>} [opts] The options for the request.
683684
* @returns {Promise<AggregateGroupByResult<T, M>[]>} The aggregated metrics for the objects returned by the vector search.
684685
*/
685686
nearImage<M extends PropertiesMetrics<T>>(
686-
image: string,
687+
image: string | Buffer,
687688
opts?: AggregateGroupByNearOptions<T, M>
688689
): Promise<AggregateGroupByResult<T, M>[]>;
689690
/**

src/collections/generate/index.ts

Lines changed: 62 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ConsistencyLevel } from '../../data/index.js';
44
import { DbVersionSupport } from '../../utils/dbVersion.js';
55

66
import { WeaviateInvalidInputError, WeaviateUnsupportedFeatureError } from '../../errors.js';
7+
import { toBase64FromMedia } from '../../index.js';
78
import { SearchReply } from '../../proto/v1/search_get.js';
89
import { Deserialize } from '../deserialize/index.js';
910
import {
@@ -160,26 +161,32 @@ class GenerateManager<T> implements Generate<T> {
160161
}
161162

162163
public nearImage(
163-
image: string,
164+
image: string | Buffer,
164165
generate: GenerateOptions<T>,
165166
opts?: BaseNearOptions<T>
166167
): Promise<GenerativeReturn<T>>;
167168
public nearImage(
168-
image: string,
169+
image: string | Buffer,
169170
generate: GenerateOptions<T>,
170171
opts: GroupByNearOptions<T>
171172
): Promise<GenerativeGroupByReturn<T>>;
172-
public nearImage(image: string, generate: GenerateOptions<T>, opts?: NearOptions<T>): GenerateReturn<T> {
173+
public nearImage(
174+
image: string | Buffer,
175+
generate: GenerateOptions<T>,
176+
opts?: NearOptions<T>
177+
): GenerateReturn<T> {
173178
return this.checkSupportForNamedVectors(opts)
174179
.then(() => this.connection.search(this.name, this.consistencyLevel, this.tenant))
175180
.then((search) =>
176-
search.withNearImage({
177-
...Serialize.nearImage({ image, ...(opts ? opts : {}) }),
178-
generative: Serialize.generative(generate),
179-
groupBy: Serialize.isGroupBy<GroupByNearOptions<T>>(opts)
180-
? Serialize.groupBy(opts.groupBy)
181-
: undefined,
182-
})
181+
toBase64FromMedia(image).then((image) =>
182+
search.withNearImage({
183+
...Serialize.nearImage({ image, ...(opts ? opts : {}) }),
184+
generative: Serialize.generative(generate),
185+
groupBy: Serialize.isGroupBy<GroupByNearOptions<T>>(opts)
186+
? Serialize.groupBy(opts.groupBy)
187+
: undefined,
188+
})
189+
)
183190
)
184191
.then((reply) => this.parseGroupByReply(opts, reply));
185192
}
@@ -268,19 +275,19 @@ class GenerateManager<T> implements Generate<T> {
268275
}
269276

270277
public nearMedia(
271-
media: string,
278+
media: string | Buffer,
272279
type: NearMediaType,
273280
generate: GenerateOptions<T>,
274281
opts?: BaseNearOptions<T>
275282
): Promise<GenerativeReturn<T>>;
276283
public nearMedia(
277-
media: string,
284+
media: string | Buffer,
278285
type: NearMediaType,
279286
generate: GenerateOptions<T>,
280287
opts: GroupByNearOptions<T>
281288
): Promise<GenerativeGroupByReturn<T>>;
282289
public nearMedia(
283-
media: string,
290+
media: string | Buffer,
284291
type: NearMediaType,
285292
generate: GenerateOptions<T>,
286293
opts?: NearOptions<T>
@@ -295,46 +302,58 @@ class GenerateManager<T> implements Generate<T> {
295302
: undefined;
296303
switch (type) {
297304
case 'audio':
298-
reply = search.withNearAudio({
299-
...Serialize.nearAudio({ audio: media, ...(opts ? opts : {}) }),
300-
generative,
301-
groupBy,
302-
});
305+
reply = toBase64FromMedia(media).then((media) =>
306+
search.withNearAudio({
307+
...Serialize.nearAudio({ audio: media, ...(opts ? opts : {}) }),
308+
generative,
309+
groupBy,
310+
})
311+
);
303312
break;
304313
case 'depth':
305-
reply = search.withNearDepth({
306-
...Serialize.nearDepth({ depth: media, ...(opts ? opts : {}) }),
307-
generative,
308-
groupBy,
309-
});
314+
reply = toBase64FromMedia(media).then((media) =>
315+
search.withNearDepth({
316+
...Serialize.nearDepth({ depth: media, ...(opts ? opts : {}) }),
317+
generative,
318+
groupBy,
319+
})
320+
);
310321
break;
311322
case 'image':
312-
reply = search.withNearImage({
313-
...Serialize.nearImage({ image: media, ...(opts ? opts : {}) }),
314-
generative,
315-
groupBy,
316-
});
323+
reply = toBase64FromMedia(media).then((media) =>
324+
search.withNearImage({
325+
...Serialize.nearImage({ image: media, ...(opts ? opts : {}) }),
326+
generative,
327+
groupBy,
328+
})
329+
);
317330
break;
318331
case 'imu':
319-
reply = search.withNearIMU({
320-
...Serialize.nearIMU({ imu: media, ...(opts ? opts : {}) }),
321-
generative,
322-
groupBy,
323-
});
332+
reply = toBase64FromMedia(media).then((media) =>
333+
search.withNearIMU({
334+
...Serialize.nearIMU({ imu: media, ...(opts ? opts : {}) }),
335+
generative,
336+
groupBy,
337+
})
338+
);
324339
break;
325340
case 'thermal':
326-
reply = search.withNearThermal({
327-
...Serialize.nearThermal({ thermal: media, ...(opts ? opts : {}) }),
328-
generative,
329-
groupBy,
330-
});
341+
reply = toBase64FromMedia(media).then((media) =>
342+
search.withNearThermal({
343+
...Serialize.nearThermal({ thermal: media, ...(opts ? opts : {}) }),
344+
generative,
345+
groupBy,
346+
})
347+
);
331348
break;
332349
case 'video':
333-
reply = search.withNearVideo({
334-
...Serialize.nearVideo({ video: media, ...(opts ? opts : {}) }),
335-
generative,
336-
groupBy,
337-
});
350+
reply = toBase64FromMedia(media).then((media) =>
351+
search.withNearVideo({
352+
...Serialize.nearVideo({ video: media, ...(opts ? opts : {}) }),
353+
generative,
354+
groupBy,
355+
})
356+
);
338357
break;
339358
default:
340359
throw new WeaviateInvalidInputError(`Invalid media type: ${type}`);

0 commit comments

Comments
 (0)