@@ -17,6 +17,10 @@ import (
1717 "go.mongodb.org/atlas-sdk/v20231115001/admin"
1818)
1919
20+ const (
21+ vectorSearch = "vectorSearch"
22+ )
23+
2024func resourceMongoDBAtlasSearchIndex () * schema.Resource {
2125 return & schema.Resource {
2226 CreateWithoutTimeout : resourceMongoDBAtlasSearchIndexCreate ,
@@ -115,6 +119,15 @@ func returnSearchIndexSchema() map[string]*schema.Schema {
115119 Type : schema .TypeBool ,
116120 Optional : true ,
117121 },
122+ "type" : {
123+ Type : schema .TypeString ,
124+ Optional : true ,
125+ },
126+ "fields" : {
127+ Type : schema .TypeString ,
128+ Optional : true ,
129+ DiffSuppressFunc : validateSearchIndexMappingDiff ,
130+ },
118131 }
119132}
120133
@@ -181,12 +194,12 @@ func resourceMongoDBAtlasSearchIndexUpdate(ctx context.Context, d *schema.Resour
181194 return diag .Errorf ("error getting search index information: %s" , err )
182195 }
183196
184- if d .HasChange ("analyzer " ) {
185- searchIndex .Analyzer = stringPtr (d .Get ("analyzer " ).(string ))
197+ if d .HasChange ("type " ) {
198+ searchIndex .Type = stringPtr (d .Get ("type " ).(string ))
186199 }
187200
188- if d .HasChange ("analyzers " ) {
189- searchIndex .Analyzers = unmarshalSearchIndexAnalyzersFields (d .Get ("analyzers " ).(string ))
201+ if d .HasChange ("analyzer " ) {
202+ searchIndex .Analyzer = stringPtr (d .Get ("analyzer " ).(string ))
190203 }
191204
192205 if d .HasChange ("collection_name" ) {
@@ -210,8 +223,28 @@ func resourceMongoDBAtlasSearchIndexUpdate(ctx context.Context, d *schema.Resour
210223 searchIndex .Mappings .Dynamic = & dynamic
211224 }
212225
226+ if d .HasChange ("analyzers" ) {
227+ analyzers , err := unmarshalSearchIndexAnalyzersFields (d .Get ("analyzers" ).(string ))
228+ if err != nil {
229+ return err
230+ }
231+ searchIndex .Analyzers = analyzers
232+ }
233+
213234 if d .HasChange ("mappings_fields" ) {
214- searchIndex .Mappings .Fields = unmarshalSearchIndexMappingFields (d .Get ("mappings_fields" ).(string ))
235+ mappingsFields , err := unmarshalSearchIndexMappingFields (d .Get ("mappings_fields" ).(string ))
236+ if err != nil {
237+ return err
238+ }
239+ searchIndex .Mappings .Fields = mappingsFields
240+ }
241+
242+ if d .HasChange ("fields" ) {
243+ fields , err := unmarshalSearchIndexFields (d .Get ("fields" ).(string ))
244+ if err != nil {
245+ return err
246+ }
247+ searchIndex .Fields = fields
215248 }
216249
217250 if d .HasChange ("synonyms" ) {
@@ -272,6 +305,10 @@ func resourceMongoDBAtlasSearchIndexRead(ctx context.Context, d *schema.Resource
272305 return diag .Errorf ("error setting `index_id` for search index (%s): %s" , d .Id (), err )
273306 }
274307
308+ if err := d .Set ("type" , searchIndex .Type ); err != nil {
309+ return diag .Errorf ("error setting `type` for search index (%s): %s" , d .Id (), err )
310+ }
311+
275312 if err := d .Set ("analyzer" , searchIndex .Analyzer ); err != nil {
276313 return diag .Errorf ("error setting `analyzer` for search index (%s): %s" , d .Id (), err )
277314 }
@@ -283,7 +320,7 @@ func resourceMongoDBAtlasSearchIndexRead(ctx context.Context, d *schema.Resource
283320 }
284321
285322 if err := d .Set ("analyzers" , searchIndexMappingFields ); err != nil {
286- return diag .Errorf ("error setting `analyzer ` for search index (%s): %s" , d .Id (), err )
323+ return diag .Errorf ("error setting `analyzers ` for search index (%s): %s" , d .Id (), err )
287324 }
288325 }
289326
@@ -303,22 +340,35 @@ func resourceMongoDBAtlasSearchIndexRead(ctx context.Context, d *schema.Resource
303340 return diag .Errorf ("error setting `searchAnalyzer` for search index (%s): %s" , d .Id (), err )
304341 }
305342
306- if err := d .Set ("mappings_dynamic" , searchIndex .Mappings .Dynamic ); err != nil {
307- return diag .Errorf ("error setting `mappings_dynamic` for search index (%s): %s" , d .Id (), err )
308- }
309-
310343 if err := d .Set ("synonyms" , flattenSearchIndexSynonyms (searchIndex .Synonyms )); err != nil {
311344 return diag .Errorf ("error setting `synonyms` for search index (%s): %s" , d .Id (), err )
312345 }
313346
314- if len (searchIndex .Mappings .Fields ) > 0 {
315- searchIndexMappingFields , err := marshalSearchIndex (searchIndex .Mappings .Fields )
347+ if searchIndex .Mappings != nil {
348+ if err := d .Set ("mappings_dynamic" , searchIndex .Mappings .Dynamic ); err != nil {
349+ return diag .Errorf ("error setting `mappings_dynamic` for search index (%s): %s" , d .Id (), err )
350+ }
351+
352+ if len (searchIndex .Mappings .Fields ) > 0 {
353+ searchIndexMappingFields , err := marshalSearchIndex (searchIndex .Mappings .Fields )
354+ if err != nil {
355+ return diag .FromErr (err )
356+ }
357+
358+ if err := d .Set ("mappings_fields" , searchIndexMappingFields ); err != nil {
359+ return diag .Errorf ("error setting `mappings_fields` for for search index (%s): %s" , d .Id (), err )
360+ }
361+ }
362+ }
363+
364+ if len (searchIndex .Fields ) > 0 {
365+ fields , err := marshalSearchIndex (searchIndex .Fields )
316366 if err != nil {
317367 return diag .FromErr (err )
318368 }
319369
320- if err := d .Set ("mappings_fields " , searchIndexMappingFields ); err != nil {
321- return diag .Errorf ("error setting `mappings_fields ` for for search index (%s): %s" , d .Id (), err )
370+ if err := d .Set ("fields " , fields ); err != nil {
371+ return diag .Errorf ("error setting `fields ` for for search index (%s): %s" , d .Id (), err )
322372 }
323373 }
324374
@@ -346,21 +396,42 @@ func resourceMongoDBAtlasSearchIndexCreate(ctx context.Context, d *schema.Resour
346396 connV2 := meta .(* MongoDBClient ).AtlasV2
347397 projectID := d .Get ("project_id" ).(string )
348398 clusterName := d .Get ("cluster_name" ).(string )
349- dynamic := d .Get ("mappings_dynamic" ).(bool )
399+ indexType := d .Get ("type" ).(string )
400+
350401 searchIndexRequest := & admin.ClusterSearchIndex {
402+ Type : stringPtr (indexType ),
351403 Analyzer : stringPtr (d .Get ("analyzer" ).(string )),
352- Analyzers : unmarshalSearchIndexAnalyzersFields (d .Get ("analyzers" ).(string )),
353404 CollectionName : d .Get ("collection_name" ).(string ),
354405 Database : d .Get ("database" ).(string ),
355- Mappings : & admin.ApiAtlasFTSMappings {
356- Dynamic : & dynamic ,
357- Fields : unmarshalSearchIndexMappingFields (d .Get ("mappings_fields" ).(string )),
358- },
359406 Name : d .Get ("name" ).(string ),
360407 SearchAnalyzer : stringPtr (d .Get ("search_analyzer" ).(string )),
361408 Status : stringPtr (d .Get ("status" ).(string )),
362409 Synonyms : expandSearchIndexSynonyms (d ),
363410 }
411+
412+ if indexType == vectorSearch {
413+ fields , err := unmarshalSearchIndexFields (d .Get ("fields" ).(string ))
414+ if err != nil {
415+ return err
416+ }
417+ searchIndexRequest .Fields = fields
418+ } else {
419+ analyzers , err := unmarshalSearchIndexAnalyzersFields (d .Get ("analyzers" ).(string ))
420+ if err != nil {
421+ return err
422+ }
423+ searchIndexRequest .Analyzers = analyzers
424+ mappingsFields , err := unmarshalSearchIndexMappingFields (d .Get ("mappings_fields" ).(string ))
425+ if err != nil {
426+ return err
427+ }
428+ dynamic := d .Get ("mappings_dynamic" ).(bool )
429+ searchIndexRequest .Mappings = & admin.ApiAtlasFTSMappings {
430+ Dynamic : & dynamic ,
431+ Fields : mappingsFields ,
432+ }
433+ }
434+
364435 dbSearchIndexRes , _ , err := connV2 .AtlasSearchApi .CreateAtlasSearchIndex (ctx , projectID , clusterName , searchIndexRequest ).Execute ()
365436 if err != nil {
366437 return diag .Errorf ("error creating index: %s" , err )
@@ -467,28 +538,38 @@ func validateSearchAnalyzersDiff(k, old, newStr string, d *schema.ResourceData)
467538 return true
468539}
469540
470- func unmarshalSearchIndexMappingFields (mappingString string ) map [string ]any {
541+ func unmarshalSearchIndexMappingFields (mappingString string ) ( map [string ]any , diag. Diagnostics ) {
471542 if mappingString == "" {
472- return nil
543+ return nil , nil
473544 }
474545 var fields map [string ]any
475546 if err := json .Unmarshal ([]byte (mappingString ), & fields ); err != nil {
476- log .Printf ("[ERROR] cannot unmarshal search index mapping fields: %v" , err )
477- return nil
547+ return nil , diag .Errorf ("cannot unmarshal search index attribute `mappings_fields` because it has an incorrect format" )
478548 }
479- return fields
549+ return fields , nil
550+ }
551+
552+ func unmarshalSearchIndexFields (fieldsStr string ) ([]map [string ]any , diag.Diagnostics ) {
553+ if fieldsStr == "" {
554+ return nil , nil
555+ }
556+ var fields []map [string ]any
557+ if err := json .Unmarshal ([]byte (fieldsStr ), & fields ); err != nil {
558+ return nil , diag .Errorf ("cannot unmarshal search index attribute `fields` because it has an incorrect format" )
559+ }
560+
561+ return fields , nil
480562}
481563
482- func unmarshalSearchIndexAnalyzersFields (mappingString string ) []admin.ApiAtlasFTSAnalyzers {
564+ func unmarshalSearchIndexAnalyzersFields (mappingString string ) ( []admin.ApiAtlasFTSAnalyzers , diag. Diagnostics ) {
483565 if mappingString == "" {
484- return nil
566+ return nil , nil
485567 }
486568 var fields []admin.ApiAtlasFTSAnalyzers
487569 if err := json .Unmarshal ([]byte (mappingString ), & fields ); err != nil {
488- log .Printf ("[ERROR] cannot unmarshal search index mapping fields: %v" , err )
489- return nil
570+ return nil , diag .Errorf ("cannot unmarshal search index attribute `analyzers` because it has an incorrect format" )
490571 }
491- return fields
572+ return fields , nil
492573}
493574
494575func resourceSearchIndexRefreshFunc (ctx context.Context , clusterName , projectID , indexID string , connV2 * admin.APIClient ) retry.StateRefreshFunc {
0 commit comments