Skip to content

Commit 1eb9bd3

Browse files
committed
Support AddCollectionStructField interface
Signed-off-by: yhmo <yihua.mo@zilliz.com>
1 parent a873189 commit 1eb9bd3

8 files changed

Lines changed: 437 additions & 2 deletions

File tree

sdk-core/src/main/java/io/milvus/v2/client/MilvusClientV2.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,15 @@ public void addCollectionField(AddCollectionFieldReq request) {
489489
rpcUtils.retry(() -> collectionService.addCollectionField(this.getRpcStub(), request));
490490
}
491491

492+
/**
493+
* Add a new struct field to collection.
494+
*
495+
* @param request add new struct field request
496+
*/
497+
public void addCollectionStructField(AddCollectionStructFieldReq request) {
498+
rpcUtils.retry(() -> collectionService.addCollectionStructField(this.getRpcStub(), request));
499+
}
500+
492501
/**
493502
* Alter a field's properties.
494503
*

sdk-core/src/main/java/io/milvus/v2/service/collection/CollectionService.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,24 @@ public Void addCollectionField(MilvusServiceGrpc.MilvusServiceBlockingStub block
301301
return null;
302302
}
303303

304+
public Void addCollectionStructField(MilvusServiceGrpc.MilvusServiceBlockingStub blockingStub, AddCollectionStructFieldReq request) {
305+
String dbName = request.getDatabaseName();
306+
String collectionName = request.getCollectionName();
307+
String title = String.format("Add struct field to collection: '%s' in database: '%s'", collectionName, dbName);
308+
309+
AddCollectionStructFieldRequest.Builder builder = AddCollectionStructFieldRequest.newBuilder()
310+
.setCollectionName(collectionName)
311+
.setStructArrayFieldSchema(SchemaUtils.convertToGrpcStructFieldSchema(request.toStructFieldSchema()));
312+
if (StringUtils.isNotEmpty(dbName)) {
313+
builder.setDbName(dbName);
314+
}
315+
316+
Status response = blockingStub.addCollectionStructField(builder.build());
317+
rpcUtils.handleResponse(title, response);
318+
319+
return null;
320+
}
321+
304322
public Void alterCollectionField(MilvusServiceGrpc.MilvusServiceBlockingStub blockingStub, AlterCollectionFieldReq request) {
305323
String dbName = request.getDatabaseName();
306324
String collectionName = request.getCollectionName();
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package io.milvus.v2.service.collection.request;
21+
22+
import io.milvus.exception.ParamException;
23+
import io.milvus.v2.exception.ErrorCode;
24+
import io.milvus.v2.exception.MilvusClientException;
25+
import io.milvus.v2.service.collection.request.CreateCollectionReq.FieldSchema;
26+
import io.milvus.v2.utils.SchemaUtils;
27+
28+
import java.util.ArrayList;
29+
import java.util.HashMap;
30+
import java.util.List;
31+
import java.util.Map;
32+
33+
public class AddCollectionStructFieldReq {
34+
private String collectionName;
35+
private String databaseName;
36+
private String fieldName;
37+
private String description;
38+
private Integer maxCapacity;
39+
private Boolean nullable;
40+
private List<FieldSchema> structFields;
41+
private Map<String, String> typeParams;
42+
43+
private AddCollectionStructFieldReq(AddCollectionStructFieldReqBuilder builder) {
44+
this.collectionName = builder.collectionName;
45+
this.databaseName = builder.databaseName;
46+
this.fieldName = builder.fieldName;
47+
this.description = builder.description;
48+
this.maxCapacity = builder.maxCapacity;
49+
this.nullable = builder.nullable;
50+
this.structFields = builder.structFields;
51+
this.typeParams = builder.typeParams;
52+
}
53+
54+
public String getCollectionName() {
55+
return collectionName;
56+
}
57+
58+
public void setCollectionName(String collectionName) {
59+
this.collectionName = collectionName;
60+
}
61+
62+
public String getDatabaseName() {
63+
return databaseName;
64+
}
65+
66+
public void setDatabaseName(String databaseName) {
67+
this.databaseName = databaseName;
68+
}
69+
70+
public String getFieldName() {
71+
return fieldName;
72+
}
73+
74+
public void setFieldName(String fieldName) {
75+
this.fieldName = fieldName;
76+
}
77+
78+
public String getDescription() {
79+
return description;
80+
}
81+
82+
public void setDescription(String description) {
83+
this.description = description;
84+
}
85+
86+
public Integer getMaxCapacity() {
87+
return maxCapacity;
88+
}
89+
90+
public void setMaxCapacity(Integer maxCapacity) {
91+
this.maxCapacity = maxCapacity;
92+
}
93+
94+
public Boolean getNullable() {
95+
return nullable;
96+
}
97+
98+
public void setNullable(Boolean nullable) {
99+
this.nullable = nullable;
100+
}
101+
102+
public List<FieldSchema> getStructFields() {
103+
return structFields;
104+
}
105+
106+
public void setStructFields(List<FieldSchema> structFields) {
107+
this.structFields = structFields;
108+
}
109+
110+
public Map<String, String> getTypeParams() {
111+
return typeParams;
112+
}
113+
114+
public void setTypeParams(Map<String, String> typeParams) {
115+
this.typeParams = typeParams;
116+
}
117+
118+
public CreateCollectionReq.StructFieldSchema toStructFieldSchema() {
119+
if (Boolean.FALSE.equals(nullable)) {
120+
throw new MilvusClientException(ErrorCode.INVALID_PARAMS,
121+
"Adding struct field to existing collection requires nullable=true");
122+
}
123+
124+
AddFieldReq addFieldReq = AddFieldReq.builder()
125+
.fieldName(fieldName)
126+
.description(description)
127+
.maxCapacity(maxCapacity)
128+
.structFields(structFields)
129+
.build();
130+
try {
131+
CreateCollectionReq.StructFieldSchema structFieldSchema = SchemaUtils.convertFieldReqToStructFieldSchema(addFieldReq);
132+
structFieldSchema.setNullable(Boolean.TRUE);
133+
structFieldSchema.setTypeParams(typeParams);
134+
return structFieldSchema;
135+
} catch (ParamException e) {
136+
throw new MilvusClientException(ErrorCode.INVALID_PARAMS, e.getMessage());
137+
}
138+
}
139+
140+
@Override
141+
public String toString() {
142+
return "AddCollectionStructFieldReq{" +
143+
"collectionName='" + collectionName + '\'' +
144+
", databaseName='" + databaseName + '\'' +
145+
", fieldName='" + fieldName + '\'' +
146+
", description='" + description + '\'' +
147+
", maxCapacity=" + maxCapacity +
148+
", nullable=" + nullable +
149+
", structFields=" + structFields +
150+
", typeParams=" + typeParams +
151+
'}';
152+
}
153+
154+
public static AddCollectionStructFieldReqBuilder builder() {
155+
return new AddCollectionStructFieldReqBuilder();
156+
}
157+
158+
public static class AddCollectionStructFieldReqBuilder {
159+
private String collectionName = "";
160+
private String databaseName = "";
161+
private String fieldName = "";
162+
private String description = "";
163+
private Integer maxCapacity;
164+
private Boolean nullable = Boolean.TRUE;
165+
private List<FieldSchema> structFields = new ArrayList<>();
166+
private Map<String, String> typeParams = new HashMap<>();
167+
168+
private AddCollectionStructFieldReqBuilder() {
169+
}
170+
171+
public AddCollectionStructFieldReqBuilder collectionName(String collectionName) {
172+
this.collectionName = collectionName;
173+
return this;
174+
}
175+
176+
public AddCollectionStructFieldReqBuilder databaseName(String databaseName) {
177+
this.databaseName = databaseName;
178+
return this;
179+
}
180+
181+
public AddCollectionStructFieldReqBuilder fieldName(String fieldName) {
182+
this.fieldName = fieldName;
183+
return this;
184+
}
185+
186+
public AddCollectionStructFieldReqBuilder description(String description) {
187+
this.description = description;
188+
return this;
189+
}
190+
191+
public AddCollectionStructFieldReqBuilder maxCapacity(Integer maxCapacity) {
192+
this.maxCapacity = maxCapacity;
193+
return this;
194+
}
195+
196+
public AddCollectionStructFieldReqBuilder nullable(Boolean nullable) {
197+
this.nullable = nullable;
198+
return this;
199+
}
200+
201+
public AddCollectionStructFieldReqBuilder structFields(List<FieldSchema> structFields) {
202+
this.structFields = structFields;
203+
return this;
204+
}
205+
206+
public AddCollectionStructFieldReqBuilder addStructField(AddFieldReq addFieldReq) {
207+
if (this.structFields == null) {
208+
this.structFields = new ArrayList<>();
209+
}
210+
this.structFields.add(SchemaUtils.convertFieldReqToFieldSchema(addFieldReq));
211+
return this;
212+
}
213+
214+
public AddCollectionStructFieldReqBuilder typeParams(Map<String, String> typeParams) {
215+
this.typeParams = typeParams;
216+
return this;
217+
}
218+
219+
public AddCollectionStructFieldReqBuilder typeParam(String key, String value) {
220+
if (this.typeParams == null) {
221+
this.typeParams = new HashMap<>();
222+
}
223+
this.typeParams.put(key, value);
224+
return this;
225+
}
226+
227+
public AddCollectionStructFieldReq build() {
228+
return new AddCollectionStructFieldReq(this);
229+
}
230+
}
231+
}

sdk-core/src/main/java/io/milvus/v2/service/collection/request/CreateCollectionReq.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,12 +1056,16 @@ public static class StructFieldSchema {
10561056
private String description = "";
10571057
private List<CreateCollectionReq.FieldSchema> fields = new ArrayList<>();
10581058
private Integer maxCapacity;
1059+
private Boolean nullable = Boolean.FALSE;
1060+
private Map<String, String> typeParams = new HashMap<>();
10591061

10601062
private StructFieldSchema(StructFieldSchemaBuilder builder) {
10611063
this.name = builder.name;
10621064
this.description = builder.description;
10631065
this.fields = builder.fields;
10641066
this.maxCapacity = builder.maxCapacity;
1067+
this.nullable = Boolean.TRUE.equals(builder.nullable);
1068+
this.typeParams = builder.typeParams;
10651069
}
10661070

10671071
public StructFieldSchema addField(AddFieldReq addFieldReq) {
@@ -1113,13 +1117,31 @@ public void setMaxCapacity(Integer maxCapacity) {
11131117
this.maxCapacity = maxCapacity;
11141118
}
11151119

1120+
public Boolean getNullable() {
1121+
return nullable;
1122+
}
1123+
1124+
public void setNullable(Boolean nullable) {
1125+
this.nullable = Boolean.TRUE.equals(nullable);
1126+
}
1127+
1128+
public Map<String, String> getTypeParams() {
1129+
return typeParams;
1130+
}
1131+
1132+
public void setTypeParams(Map<String, String> typeParams) {
1133+
this.typeParams = typeParams;
1134+
}
1135+
11161136
@Override
11171137
public String toString() {
11181138
return "StructFieldSchema{" +
11191139
"name='" + name + '\'' +
11201140
", description='" + description + '\'' +
11211141
", fields=" + fields +
11221142
", maxCapacity=" + maxCapacity +
1143+
", nullable=" + nullable +
1144+
", typeParams=" + typeParams +
11231145
'}';
11241146
}
11251147

@@ -1132,6 +1154,8 @@ public static class StructFieldSchemaBuilder {
11321154
private String description = "";
11331155
private List<CreateCollectionReq.FieldSchema> fields = new ArrayList<>();
11341156
private Integer maxCapacity;
1157+
private Boolean nullable = Boolean.FALSE;
1158+
private Map<String, String> typeParams = new HashMap<>();
11351159

11361160
private StructFieldSchemaBuilder() {
11371161
}
@@ -1156,6 +1180,24 @@ public StructFieldSchemaBuilder maxCapacity(Integer maxCapacity) {
11561180
return this;
11571181
}
11581182

1183+
public StructFieldSchemaBuilder nullable(Boolean nullable) {
1184+
this.nullable = Boolean.TRUE.equals(nullable);
1185+
return this;
1186+
}
1187+
1188+
public StructFieldSchemaBuilder typeParams(Map<String, String> typeParams) {
1189+
this.typeParams = typeParams;
1190+
return this;
1191+
}
1192+
1193+
public StructFieldSchemaBuilder typeParam(String key, String value) {
1194+
if (this.typeParams == null) {
1195+
this.typeParams = new HashMap<>();
1196+
}
1197+
this.typeParams.put(key, value);
1198+
return this;
1199+
}
1200+
11591201
public StructFieldSchema build() {
11601202
return new StructFieldSchema(this);
11611203
}

sdk-core/src/main/java/io/milvus/v2/utils/SchemaUtils.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,13 @@ public static StructArrayFieldSchema convertToGrpcStructFieldSchema(CreateCollec
158158
checkNullEmptyString(structSchema.getName(), "Field name");
159159
StructArrayFieldSchema.Builder builder = StructArrayFieldSchema.newBuilder()
160160
.setName(structSchema.getName())
161-
.setDescription(structSchema.getDescription());
161+
.setDescription(structSchema.getDescription())
162+
.setNullable(Boolean.TRUE.equals(structSchema.getNullable()));
163+
164+
List<KeyValuePair> typeParamsList = AssembleKvPair(structSchema.getTypeParams());
165+
if (CollectionUtils.isNotEmpty(typeParamsList)) {
166+
typeParamsList.forEach(builder::addTypeParams);
167+
}
162168

163169
for (CreateCollectionReq.FieldSchema field : structSchema.getFields()) {
164170
DataType actualType = DataType.Array;
@@ -286,7 +292,12 @@ public static CreateCollectionReq.StructFieldSchema convertFromGrpcStructFieldSc
286292
CreateCollectionReq.StructFieldSchema.StructFieldSchemaBuilder builder =
287293
CreateCollectionReq.StructFieldSchema.builder()
288294
.name(structSchema.getName())
289-
.description(structSchema.getDescription());
295+
.description(structSchema.getDescription())
296+
.nullable(structSchema.getNullable());
297+
List<KeyValuePair> structTypeParams = structSchema.getTypeParamsList();
298+
if (CollectionUtils.isNotEmpty(structTypeParams)) {
299+
structTypeParams.forEach((kv) -> builder.typeParam(kv.getKey(), kv.getValue()));
300+
}
290301
List<CreateCollectionReq.FieldSchema> fields = new ArrayList<>();
291302
for (FieldSchema fieldSchema : structSchema.getFieldsList()) {
292303
CreateCollectionReq.FieldSchema field = convertFromGrpcFieldSchema(fieldSchema);

sdk-core/src/test/java/io/milvus/v2/BaseTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ public void setUp() {
107107
// collection api
108108
when(blockingStub.showCollections(any(ShowCollectionsRequest.class))).thenReturn(ShowCollectionsResponse.newBuilder().setStatus(successStatus).addAllCollectionNames(Collections.singletonList("test")).build());
109109
when(blockingStub.createCollection(any(CreateCollectionRequest.class))).thenReturn(successStatus);
110+
when(blockingStub.addCollectionStructField(any())).thenReturn(successStatus);
110111
when(blockingStub.loadCollection(any())).thenReturn(successStatus);
111112
when(blockingStub.releaseCollection(any())).thenReturn(successStatus);
112113
when(blockingStub.getLoadState(any())).thenReturn(GetLoadStateResponse.newBuilder().setState(LoadState.LoadStateLoaded).setStatus(successStatus).build());

0 commit comments

Comments
 (0)