1
1
/*
2
- * Copyright 2024 the original author or authors.
2
+ * Copyright 2025 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
18
18
import java .util .ArrayList ;
19
19
import java .util .List ;
20
20
21
+ import org .bson .BsonString ;
21
22
import org .bson .Document ;
22
-
23
23
import org .springframework .data .mapping .context .MappingContext ;
24
24
import org .springframework .data .mongodb .core .MongoOperations ;
25
- import org .springframework .data .mongodb .core .aggregation .Aggregation ;
26
- import org .springframework .data .mongodb .core .aggregation .AggregationResults ;
27
25
import org .springframework .data .mongodb .core .mapping .MongoPersistentEntity ;
28
26
import org .springframework .data .mongodb .core .mapping .MongoPersistentProperty ;
29
27
import org .springframework .data .util .TypeInformation ;
30
28
import org .springframework .lang .Nullable ;
29
+ import org .springframework .util .StringUtils ;
31
30
32
31
import com .mongodb .client .model .SearchIndexModel ;
33
32
import com .mongodb .client .model .SearchIndexType ;
34
33
35
34
/**
36
35
* @author Christoph Strobl
37
36
* @author Mark Paluch
38
- * @since 3 .5
37
+ * @since 4 .5
39
38
*/
40
39
public class DefaultSearchIndexOperations implements SearchIndexOperations {
41
40
@@ -48,6 +47,7 @@ public DefaultSearchIndexOperations(MongoOperations mongoOperations, Class<?> ty
48
47
}
49
48
50
49
public DefaultSearchIndexOperations (MongoOperations mongoOperations , String collectionName , @ Nullable Class <?> type ) {
50
+
51
51
this .collectionName = collectionName ;
52
52
53
53
if (type != null ) {
@@ -63,80 +63,63 @@ public DefaultSearchIndexOperations(MongoOperations mongoOperations, String coll
63
63
}
64
64
65
65
@ Override
66
- public String ensureIndex (SearchIndexDefinition indexDefinition ) {
67
-
68
- if (!(indexDefinition instanceof VectorIndex vsi )) {
69
- throw new IllegalStateException ("Index definitions must be of type VectorIndex" );
70
- }
66
+ public String createIndex (SearchIndexDefinition indexDefinition ) {
71
67
72
68
Document index = indexDefinition .getIndexDocument (entityTypeInformation ,
73
69
mongoOperations .getConverter ().getMappingContext ());
74
70
75
- mongoOperations .getCollection (collectionName ).createSearchIndexes (List
76
- .of (new SearchIndexModel (vsi .getName (), (Document ) index .get ("definition" ), SearchIndexType .vectorSearch ())));
71
+ mongoOperations .getCollection (collectionName )
72
+ .createSearchIndexes (List .of (new SearchIndexModel (indexDefinition .getName (),
73
+ index .get ("definition" , Document .class ), SearchIndexType .of (new BsonString (indexDefinition .getType ())))));
77
74
78
- return vsi .getName ();
75
+ return indexDefinition .getName ();
79
76
}
80
77
81
78
@ Override
82
- public void updateIndex (SearchIndexDefinition index ) {
83
-
84
- if (index instanceof VectorIndex ) {
85
- throw new UnsupportedOperationException ("Vector Index definitions cannot be updated" );
86
- }
79
+ public void updateIndex (SearchIndexDefinition indexDefinition ) {
87
80
88
- Document indexDocument = index .getIndexDocument (entityTypeInformation ,
81
+ Document indexDocument = indexDefinition .getIndexDocument (entityTypeInformation ,
89
82
mongoOperations .getConverter ().getMappingContext ());
90
83
91
- mongoOperations .getCollection (collectionName ).updateSearchIndex (index .getName (), indexDocument );
84
+ mongoOperations .getCollection (collectionName ).updateSearchIndex (indexDefinition .getName (), indexDocument );
92
85
}
93
86
94
87
@ Override
95
88
public boolean exists (String indexName ) {
96
-
97
- List <Document > indexes = mongoOperations .getCollection (collectionName ).listSearchIndexes ().into (new ArrayList <>());
98
-
99
- for (Document index : indexes ) {
100
- if (index .getString ("name" ).equals (indexName )) {
101
- return true ;
102
- }
103
- }
104
-
105
- return false ;
89
+ return getSearchIndex (indexName ) != null ;
106
90
}
107
91
108
92
@ Override
109
- public List <IndexInfo > getIndexInfo () {
110
-
111
- AggregationResults <Document > aggregate = mongoOperations .aggregate (
112
- Aggregation .newAggregation (context -> new Document ("$listSearchIndexes" , new Document ())), collectionName ,
113
- Document .class );
93
+ public SearchIndexStatus status (String indexName ) {
114
94
115
- ArrayList <IndexInfo > result = new ArrayList <>();
116
- for (Document doc : aggregate ) {
117
-
118
- List <IndexField > indexFields = new ArrayList <>();
119
- String name = doc .getString ("name" );
120
- for (Object field : doc .get ("latestDefinition" , Document .class ).get ("fields" , List .class )) {
121
-
122
- if (field instanceof Document fieldInfo ) {
123
- indexFields .add (IndexField .vector (fieldInfo .getString ("path" )));
124
- }
125
- }
126
-
127
- result .add (new IndexInfo (indexFields , name , false , false , null , false ));
128
- }
129
- return result ;
95
+ Document searchIndex = getSearchIndex (indexName );
96
+ return searchIndex != null ? SearchIndexStatus .valueOf (searchIndex .getString ("status" ))
97
+ : SearchIndexStatus .DOES_NOT_EXIST ;
130
98
}
131
99
132
100
@ Override
133
101
public void dropAllIndexes () {
134
- getIndexInfo ( ).forEach (indexInfo -> dropIndex (indexInfo .getName ( )));
102
+ getSearchIndexes ( null ).forEach (indexInfo -> dropIndex (indexInfo .getString ( "name" )));
135
103
}
136
104
137
105
@ Override
138
- public void dropIndex (String name ) {
139
- mongoOperations .getCollection (collectionName ).dropSearchIndex (name );
106
+ public void dropIndex (String indexName ) {
107
+ mongoOperations .getCollection (collectionName ).dropSearchIndex (indexName );
108
+ }
109
+
110
+ @ Nullable
111
+ private Document getSearchIndex (String indexName ) {
112
+
113
+ List <Document > indexes = getSearchIndexes (indexName );
114
+ return indexes .isEmpty () ? null : indexes .iterator ().next ();
115
+ }
116
+
117
+ private List <Document > getSearchIndexes (@ Nullable String indexName ) {
118
+
119
+ Document filter = StringUtils .hasText (indexName ) ? new Document ("name" , indexName ) : new Document ();
120
+
121
+ return mongoOperations .getCollection (collectionName ).aggregate (List .of (new Document ("$listSearchIndexes" , filter )))
122
+ .into (new ArrayList <>());
140
123
}
141
124
142
125
}
0 commit comments