Skip to content

Commit b2dc636

Browse files
authored
Merge pull request #180 from weaviate/hybrid/add-support-for-query-property-weights
Add `Bm25QueryProperty` type for use in weighted `.bm25` and `.hybrid`
2 parents 15a1206 + 8fb5445 commit b2dc636

File tree

3 files changed

+58
-5
lines changed

3 files changed

+58
-5
lines changed

src/collections/query/integration.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,38 @@ describe('Testing of the collection.query methods with a simple collection', ()
9494
expect(ret.objects[0].uuid).toEqual(id);
9595
});
9696

97+
it('should query with bm25 and weighted query properties', async () => {
98+
const ret = await collection.query.bm25('test', {
99+
queryProperties: [
100+
{
101+
name: 'testProp',
102+
weight: 2,
103+
},
104+
'testProp2',
105+
],
106+
});
107+
expect(ret.objects.length).toEqual(1);
108+
expect(ret.objects[0].properties.testProp).toEqual('test');
109+
expect(ret.objects[0].properties.testProp2).toEqual('test2');
110+
expect(ret.objects[0].uuid).toEqual(id);
111+
});
112+
113+
it('should query with bm25 and weighted query properties with a non-generic collection', async () => {
114+
const ret = await client.collections.get(collectionName).query.bm25('test', {
115+
queryProperties: [
116+
{
117+
name: 'testProp',
118+
weight: 2,
119+
},
120+
'testProp2',
121+
],
122+
});
123+
expect(ret.objects.length).toEqual(1);
124+
expect(ret.objects[0].properties.testProp).toEqual('test');
125+
expect(ret.objects[0].properties.testProp2).toEqual('test2');
126+
expect(ret.objects[0].uuid).toEqual(id);
127+
});
128+
97129
it('should query with hybrid', async () => {
98130
const ret = await collection.query.hybrid('test', { limit: 1 });
99131
expect(ret.objects.length).toEqual(1);

src/collections/query/types.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,18 @@ export type SearchOptions<T> = {
7676
returnReferences?: QueryReference<T>[];
7777
};
7878

79+
/** Which property of the collection to perform the keyword search on. */
80+
export type Bm25QueryProperty<T> = {
81+
/** The property name to search on. */
82+
name: PrimitiveKeys<T>;
83+
/** The weight to provide to the keyword search for this property. */
84+
weight: number;
85+
};
86+
7987
/** Base options available in the `query.bm25` method */
8088
export type BaseBm25Options<T> = SearchOptions<T> & {
8189
/** Which properties of the collection to perform the keyword search on. */
82-
queryProperties?: PrimitiveKeys<T>[];
90+
queryProperties?: (PrimitiveKeys<T> | Bm25QueryProperty<T>)[];
8391
};
8492

8593
/** Options available in the `query.bm25` method when specifying the `groupBy` parameter. */
@@ -98,7 +106,7 @@ export type BaseHybridOptions<T> = SearchOptions<T> & {
98106
/** The specific vector to search for or a specific vector subsearch. If not specified, the query is vectorized and used in the similarity search. */
99107
vector?: NearVectorInputType | HybridNearTextSubSearch | HybridNearVectorSubSearch;
100108
/** The properties to search in. If not specified, all properties are searched. */
101-
queryProperties?: PrimitiveKeys<T>[];
109+
queryProperties?: (PrimitiveKeys<T> | Bm25QueryProperty<T>)[];
102110
/** The type of fusion to apply. If not specified, the default fusion type specified by the server is used. */
103111
fusionType?: 'Ranked' | 'RelativeScore';
104112
/** Specify which vector(s) to search on if using named vectors. */

src/collections/serialize/index.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ import {
6868
PrimitiveFilterValueType,
6969
PrimitiveListFilterValueType,
7070
} from '../filters/types.js';
71-
import { MultiTargetVectorJoin } from '../index.js';
71+
import { MultiTargetVectorJoin, PrimitiveKeys } from '../index.js';
7272
import {
7373
BaseHybridOptions,
7474
BaseNearOptions,
7575
Bm25Options,
76+
Bm25QueryProperty,
7677
FetchObjectByIdOptions,
7778
FetchObjectsOptions,
7879
HybridNearTextSubSearch,
@@ -358,12 +359,24 @@ export class Serialize {
358359
};
359360
};
360361

362+
private static bm25QueryProperties = <T>(
363+
properties?: (PrimitiveKeys<T> | Bm25QueryProperty<T>)[]
364+
): string[] | undefined => {
365+
return properties?.map((property) => {
366+
if (typeof property === 'string') {
367+
return property;
368+
} else {
369+
return `${property.name}^${property.weight}`;
370+
}
371+
});
372+
};
373+
361374
public static bm25 = <T>(args: { query: string } & Bm25Options<T>): SearchBm25Args => {
362375
return {
363376
...Serialize.common(args),
364377
bm25Search: BM25.fromPartial({
365378
query: args.query,
366-
properties: args.queryProperties,
379+
properties: this.bm25QueryProperties(args.queryProperties),
367380
}),
368381
autocut: args.autoLimit,
369382
};
@@ -448,7 +461,7 @@ export class Serialize {
448461
hybridSearch: Hybrid.fromPartial({
449462
query: args.query,
450463
alpha: args.alpha ? args.alpha : 0.5,
451-
properties: args.queryProperties,
464+
properties: this.bm25QueryProperties(args.queryProperties),
452465
vectorBytes: vectorBytes,
453466
fusionType: fusionType(args.fusionType),
454467
targetVectors,

0 commit comments

Comments
 (0)