@@ -8,24 +8,171 @@ public static class Vectors
88 {
99 public static VectorConfig SelfProvided (
1010 string name = "default" ,
11- VectorIndexConfig ? indexConfig = null
12- ) => new VectorConfigBuilder ( new Vectorizer . SelfProvided ( ) ) . New ( name , indexConfig ) ;
11+ VectorIndexConfig ? indexConfig = null ,
12+ VectorIndexConfig . QuantizerConfig ? quantizerConfig = null
13+ )
14+ {
15+ var builder = new VectorConfigBuilder ( new Vectorizer . SelfProvided ( ) ) ;
16+ return indexConfig switch
17+ {
18+ VectorIndex . HNSW hnsw => builder . New ( name , hnsw , quantizerConfig ) ,
19+ VectorIndex . Flat flat => builder . New (
20+ name ,
21+ flat ,
22+ quantizerConfig is not null
23+ ? quantizerConfig as VectorIndex . Quantizers . BQ
24+ ?? throw new WeaviateClientException (
25+ "Flat index supports only BQ quantization."
26+ )
27+ : null
28+ ) ,
29+ VectorIndex . Dynamic dynamic => quantizerConfig is null
30+ ? builder . New ( name , dynamic )
31+ : throw new WeaviateClientException (
32+ "Dynamic Index must specify quantizers in their respective Vector Index Configurations."
33+ ) ,
34+ null => builder . New (
35+ name ,
36+ ( VectorIndex . HNSW ? ) null ,
37+ ( VectorIndexConfig . QuantizerConfig ? ) null
38+ ) ,
39+ _ => throw new WeaviateClientException (
40+ $ "Unsupported VectorIndexConfig type: { indexConfig . GetType ( ) . Name } "
41+ ) ,
42+ } ;
43+ }
1344
1445 public class VectorConfigBuilder ( VectorizerConfig Config )
1546 {
47+ public VectorConfig New ( string name = "default" , params string [ ] sourceProperties ) =>
48+ new (
49+ name ,
50+ vectorizer : Config with
51+ {
52+ SourceProperties = sourceProperties ,
53+ } ,
54+ vectorIndexConfig : null
55+ ) ;
56+
1657 public VectorConfig New (
17- string name = "default" ,
18- VectorIndexConfig ? indexConfig = null ,
58+ string name ,
59+ VectorIndex . HNSW ? indexConfig ,
60+ VectorIndexConfig . QuantizerConfig ? quantizerConfig = null ,
1961 params string [ ] sourceProperties
2062 ) =>
2163 new (
22- name ,
64+ name : string . IsNullOrEmpty ( name ) ? "default" : name ,
65+ vectorizer : Config with
66+ {
67+ SourceProperties = sourceProperties ,
68+ } ,
69+ vectorIndexConfig : EnrichVectorIndexConfig ( indexConfig , quantizerConfig )
70+ ) ;
71+
72+ public VectorConfig New (
73+ string name ,
74+ VectorIndex . Flat ? indexConfig ,
75+ VectorIndex . Quantizers . BQ ? quantizerConfig = null ,
76+ params string [ ] sourceProperties
77+ ) =>
78+ new (
79+ name : string . IsNullOrEmpty ( name ) ? "default" : name ,
80+ vectorizer : Config with
81+ {
82+ SourceProperties = sourceProperties ,
83+ } ,
84+ vectorIndexConfig : EnrichVectorIndexConfig ( indexConfig , quantizerConfig )
85+ ) ;
86+
87+ public VectorConfig New (
88+ string name ,
89+ VectorIndex . Dynamic ? indexConfig ,
90+ params string [ ] sourceProperties
91+ ) =>
92+ new (
93+ name : string . IsNullOrEmpty ( name ) ? "default" : name ,
2394 vectorizer : Config with
2495 {
2596 SourceProperties = sourceProperties ,
2697 } ,
2798 vectorIndexConfig : indexConfig
2899 ) ;
100+
101+ /// <summary>
102+ /// Enriches the provided <see cref="VectorIndexConfig"/> instance with the specified quantizer configuration,
103+ /// if applicable. The method updates the quantizer property of the index configuration based on its concrete type.
104+ /// </summary>
105+ /// <param name="indexConfig">
106+ /// The vector index configuration to enrich. If <c>null</c>, the method returns <c>null</c>.
107+ /// </param>
108+ /// <param name="quantizerConfig">
109+ /// The quantizer configuration to apply. If <c>null</c>, the original <paramref name="indexConfig"/> is returned unchanged.
110+ /// </param>
111+ /// <returns>
112+ /// The enriched <see cref="VectorIndexConfig"/> instance with the quantizer configuration applied, or the original
113+ /// <paramref name="indexConfig"/> if no enrichment was possible.
114+ /// </returns>
115+ private static VectorIndexConfig ? EnrichVectorIndexConfig (
116+ VectorIndexConfig ? indexConfig ,
117+ VectorIndexConfig . QuantizerConfig ? quantizerConfig
118+ )
119+ {
120+ if ( indexConfig is null )
121+ return null ;
122+
123+ if ( quantizerConfig is null )
124+ return indexConfig ;
125+
126+ if ( indexConfig is VectorIndex . HNSW hnsw )
127+ {
128+ if ( hnsw . Quantizer != null )
129+ {
130+ throw new WeaviateClientException (
131+ "HNSW index already has a quantizer configured. Overwriting is not allowed."
132+ ) ;
133+ }
134+
135+ return hnsw with
136+ {
137+ Quantizer = quantizerConfig ,
138+ } ;
139+ }
140+
141+ if ( indexConfig is VectorIndex . Flat flat )
142+ {
143+ if ( flat . Quantizer != null )
144+ {
145+ throw new WeaviateClientException (
146+ "Flat index already has a quantizer configured. Overwriting is not allowed."
147+ ) ;
148+ }
149+
150+ // Only set the Quantizer if it's of type BQ, as Flat supports only BQ quantization.
151+ if ( quantizerConfig is VectorIndex . Quantizers . BQ bq )
152+ {
153+ flat . Quantizer = bq ;
154+ }
155+ else
156+ {
157+ throw new WeaviateClientException (
158+ "Flat index supports only BQ quantization. Provided quantizer is of type: "
159+ + quantizerConfig . GetType ( ) . Name
160+ ) ;
161+ }
162+ return flat ;
163+ }
164+
165+ // Handle the case where the index configuration is of type Dynamic,
166+ // which may contain both HNSW and Flat sub-configurations.
167+ if ( indexConfig is VectorIndex . Dynamic )
168+ {
169+ throw new WeaviateClientException (
170+ "Dynamic Index must specify quantizers in their respective Vector Index Configurations."
171+ ) ;
172+ }
173+
174+ return indexConfig ;
175+ }
29176 }
30177
31178 public static VectorConfigBuilder Img2VecNeural ( string [ ] imageFields ) =>
0 commit comments