Skip to content

Commit 69d74a6

Browse files
authored
Merge pull request #489 from weaviate/v6-geo-phonenumber
v6: PhoneNumber and GeoCoordinates types
2 parents cd8f0d6 + 94a9e99 commit 69d74a6

13 files changed

Lines changed: 221 additions & 16 deletions

File tree

src/it/java/io/weaviate/integration/DataITest.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import io.weaviate.ConcurrentTest;
1515
import io.weaviate.client6.v1.api.WeaviateApiException;
1616
import io.weaviate.client6.v1.api.WeaviateClient;
17+
import io.weaviate.client6.v1.api.collections.GeoCoordinates;
18+
import io.weaviate.client6.v1.api.collections.PhoneNumber;
1719
import io.weaviate.client6.v1.api.collections.Property;
1820
import io.weaviate.client6.v1.api.collections.ReferenceProperty;
1921
import io.weaviate.client6.v1.api.collections.VectorConfig;
@@ -432,6 +434,8 @@ public void testDataTypes() throws IOException {
432434
Property.dateArray("prop_date_array"),
433435
Property.uuidArray("prop_uuid_array"),
434436
Property.textArray("prop_text_array"),
437+
Property.phoneNumber("prop_phone_number"),
438+
Property.geoCoordinates("prop_geo_coordinates"),
435439
Property.object("prop_object",
436440
p -> p.nestedProperties(
437441
Property.text("marco"))),
@@ -457,6 +461,8 @@ public void testDataTypes() throws IOException {
457461
Map.entry("prop_date_array", List.of(now, now)),
458462
Map.entry("prop_uuid_array", List.of(uuid, uuid)),
459463
Map.entry("prop_text_array", List.of("a", "b", "c")),
464+
Map.entry("prop_phone_number", PhoneNumber.international("+380 95 1433336")),
465+
Map.entry("prop_geo_coordinates", new GeoCoordinates(1f, 2f)),
460466
Map.entry("prop_object", Map.of("marco", "polo")),
461467
Map.entry("prop_object_array", List.of(Map.of("marco", "polo"))));
462468

@@ -468,8 +474,10 @@ public void testDataTypes() throws IOException {
468474
Assertions.assertThat(got).get()
469475
.extracting(WeaviateObject::properties)
470476
.asInstanceOf(InstanceOfAssertFactories.map(String.class, Object.class))
471-
.containsAllEntriesOf(want);
472-
477+
// Most of PhoneNumber fields are only present on read and are null on write.
478+
.usingRecursiveComparison()
479+
.withComparatorForType(ORMITest::comparePhoneNumbers, PhoneNumber.class)
480+
.isEqualTo(want);
473481
}
474482

475483
record Address(

src/it/java/io/weaviate/integration/ORMITest.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import io.weaviate.ConcurrentTest;
1616
import io.weaviate.client6.v1.api.WeaviateClient;
1717
import io.weaviate.client6.v1.api.collections.CollectionConfig;
18+
import io.weaviate.client6.v1.api.collections.GeoCoordinates;
19+
import io.weaviate.client6.v1.api.collections.PhoneNumber;
1820
import io.weaviate.client6.v1.api.collections.WeaviateObject;
1921
import io.weaviate.client6.v1.api.collections.annotations.Collection;
2022
import io.weaviate.client6.v1.api.collections.annotations.Property;
@@ -79,7 +81,10 @@ static record Thing(
7981
Boolean booleanBoxed,
8082
boolean[] booleanArray,
8183
Boolean[] booleanBoxedArray,
82-
List<Boolean> booleanBoxedList) {
84+
List<Boolean> booleanBoxedList,
85+
86+
PhoneNumber phoneNumber,
87+
GeoCoordinates geoCoordinates) {
8388
}
8489

8590
@BeforeClass
@@ -150,14 +155,18 @@ public void test_createCollection() throws Exception {
150155
Map.entry("booleanBoxed", "boolean"),
151156
Map.entry("booleanArray", "boolean[]"),
152157
Map.entry("booleanBoxedArray", "boolean[]"),
153-
Map.entry("booleanBoxedList", "boolean[]"));
158+
Map.entry("booleanBoxedList", "boolean[]"),
159+
160+
Map.entry("phoneNumber", "phoneNumber"),
161+
Map.entry("geoCoordinates", "geoCoordinates"));
154162
}
155163

156-
private final RecursiveComparisonConfiguration COMPARISON_CONFIG = RecursiveComparisonConfiguration.builder()
164+
private static final RecursiveComparisonConfiguration COMPARISON_CONFIG = RecursiveComparisonConfiguration.builder()
157165
// Assertj is having a really bad time comparing List<Float>,
158166
// so we'll just always return true here.
159167
.withComparatorForFields((a, b) -> 0, "floatBoxedList")
160168
.withComparatorForType((a, b) -> Double.compare(a.doubleValue(), b.doubleValue()), Number.class)
169+
.withComparatorForType(ORMITest::comparePhoneNumbers, PhoneNumber.class)
161170
.build();
162171

163172
@Test
@@ -219,7 +228,10 @@ public void test_insertAndQuery() throws Exception {
219228
boolean_,
220229
new boolean[] { boolean_ },
221230
new Boolean[] { boolean_ },
222-
List.of(boolean_));
231+
List.of(boolean_),
232+
233+
PhoneNumber.international("+380 95 1433336"),
234+
new GeoCoordinates(1f, 2f));
223235

224236
var things = client.collections.use(Thing.class);
225237

@@ -294,7 +306,10 @@ public void test_insertManyAndQuery() throws Exception {
294306
boolean_,
295307
new boolean[] { boolean_ },
296308
new Boolean[] { boolean_ },
297-
List.of(boolean_));
309+
List.of(boolean_),
310+
311+
PhoneNumber.international("+380 95 1433336"),
312+
new GeoCoordinates(1f, 2f));
298313

299314
var things = client.collections.use(Thing.class);
300315

@@ -351,7 +366,7 @@ public void test_partialScan() throws IOException {
351366
.returns(null, Song::monthlyListeners);
352367
}
353368

354-
@Test
355-
public void test_nestedProperties() throws IOException {
369+
static int comparePhoneNumbers(PhoneNumber phone1, PhoneNumber phone2) {
370+
return phone1.rawInput().compareTo(phone2.rawInput());
356371
}
357372
}

src/main/java/io/weaviate/client6/v1/api/collections/DataType.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public interface DataType {
2020
public static final String UUID_ARRAY = "uuid[]";
2121
public static final String OBJECT = "object";
2222
public static final String OBJECT_ARRAY = "object[]";
23+
public static final String PHONE_NUMBER = "phoneNumber";
24+
public static final String GEO_COORDINATES = "geoCoordinates";
2325

2426
/**
2527
* Scalar/array types which Weaviate and WeaviateClient recognize.
@@ -34,5 +36,6 @@ public interface DataType {
3436
*/
3537
public static final Set<String> KNOWN_TYPES = ImmutableSet.of(
3638
TEXT, INT, BLOB, BOOL, DATE, UUID, NUMBER, OBJECT,
37-
TEXT_ARRAY, INT_ARRAY, NUMBER_ARRAY, BOOL_ARRAY, DATE_ARRAY, UUID_ARRAY, OBJECT_ARRAY);
39+
TEXT_ARRAY, INT_ARRAY, NUMBER_ARRAY, BOOL_ARRAY, DATE_ARRAY, UUID_ARRAY, OBJECT_ARRAY,
40+
PHONE_NUMBER, GEO_COORDINATES);
3841
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.weaviate.client6.v1.api.collections;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
public record GeoCoordinates(
6+
@SerializedName("latitude") float latitude,
7+
@SerializedName("longitude") float longitude) {
8+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package io.weaviate.client6.v1.api.collections;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
public record PhoneNumber(
6+
/** Raw input data provided at creation. */
7+
@SerializedName("input") String rawInput,
8+
/**
9+
* ISO 3166-1 alpha-2 country code. Required only if the raw input does not
10+
* include an explicit country code, e.g. {@code +31}. Only present if provided
11+
* by user.
12+
*/
13+
@SerializedName("defaultCountry") String defaultCountry,
14+
/** Numerical country code. Returned by Weaviate on read. */
15+
@SerializedName("countryCode") Integer countryCode,
16+
/**
17+
* Phone number with numerical country code prepended.
18+
* Returned by Weaviate on read.
19+
*/
20+
@SerializedName("internationalFormatted") String internationalFormatted,
21+
/**
22+
* Numerical representation of the national number.
23+
* Returned by Weaviate on read.
24+
*/
25+
@SerializedName("national") Integer national,
26+
/**
27+
* Formatted national number.
28+
* Returned by Weaviate on read.
29+
*/
30+
@SerializedName("nationalFormatted") String nationalFormatted,
31+
/**
32+
* Whether the server recognized this number as valid.
33+
* Returned by Weaviate on read.
34+
*/
35+
@SerializedName("valid") Boolean valid) {
36+
37+
/**
38+
* Create national phone number (without explicit country code),
39+
* e.g. {@code "020 1234567"}
40+
*
41+
* @param country ISO 3166-1 alpha-2 country code.
42+
* @param phoneNumber Phone number.
43+
* @return PhoneNumber
44+
*/
45+
public static PhoneNumber national(String country, String phoneNumber) {
46+
return new PhoneNumber(phoneNumber, country, null, null, null, null, null);
47+
}
48+
49+
/**
50+
* Create a phone number with explicit country code,
51+
* e.g. {@code "+31 20 1234567"}
52+
*
53+
* @param phoneNumber Phone number.
54+
* @return PhoneNumber
55+
*/
56+
public static PhoneNumber international(String phoneNumber) {
57+
return new PhoneNumber(phoneNumber, null, null, null, null, null, null);
58+
}
59+
}

src/main/java/io/weaviate/client6/v1/api/collections/Property.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ public static Property objectArray(String name) {
299299
}
300300

301301
/**
302-
* Create a {@code objectArray[]} property with additional configuration.
302+
* Create a {@code object[]} property with additional configuration.
303303
*
304304
* @param name Property name.
305305
* @param fn Lambda expression for optional parameters.
@@ -308,6 +308,44 @@ public static Property objectArray(String name, Function<Builder, ObjectBuilder<
308308
return newProperty(name, DataType.OBJECT_ARRAY, fn);
309309
}
310310

311+
/**
312+
* Create a {@code phoneNumber} property.
313+
*
314+
* @param name Property name.
315+
*/
316+
public static Property phoneNumber(String name) {
317+
return phoneNumber(name, ObjectBuilder.identity());
318+
}
319+
320+
/**
321+
* Create a {@code phoneNumber} property with additional configuration.
322+
*
323+
* @param name Property name.
324+
* @param fn Lambda expression for optional parameters.
325+
*/
326+
public static Property phoneNumber(String name, Function<Builder, ObjectBuilder<Property>> fn) {
327+
return newProperty(name, DataType.PHONE_NUMBER, fn);
328+
}
329+
330+
/**
331+
* Create a {@code geoCoordinates} property.
332+
*
333+
* @param name Property name.
334+
*/
335+
public static Property geoCoordinates(String name) {
336+
return geoCoordinates(name, ObjectBuilder.identity());
337+
}
338+
339+
/**
340+
* Create a {@code geoCoordinates} property with additional configuration.
341+
*
342+
* @param name Property name.
343+
* @param fn Lambda expression for optional parameters.
344+
*/
345+
public static Property geoCoordinates(String name, Function<Builder, ObjectBuilder<Property>> fn) {
346+
return newProperty(name, DataType.GEO_COORDINATES, fn);
347+
}
348+
311349
private static Property newProperty(String name, String dataType, Function<Builder, ObjectBuilder<Property>> fn) {
312350
return fn.apply(new Builder(name, dataType)).build();
313351
}

src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
import java.util.UUID;
99

1010
import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults;
11+
import io.weaviate.client6.v1.api.collections.GeoCoordinates;
1112
import io.weaviate.client6.v1.api.collections.ObjectMetadata;
13+
import io.weaviate.client6.v1.api.collections.PhoneNumber;
1214
import io.weaviate.client6.v1.api.collections.WeaviateObject;
1315
import io.weaviate.client6.v1.internal.MapUtil;
1416
import io.weaviate.client6.v1.internal.grpc.ByteStringUtil;
@@ -181,6 +183,23 @@ private static com.google.protobuf.Value marshalValue(Object value) {
181183
protoValue.setBoolValue(v.booleanValue());
182184
} else if (value instanceof Number v) {
183185
protoValue.setNumberValue(v.doubleValue());
186+
} else if (value instanceof PhoneNumber phone) {
187+
var phoneProto = com.google.protobuf.Struct.newBuilder();
188+
if (phone.rawInput() != null) {
189+
var input = com.google.protobuf.Value.newBuilder().setStringValue(phone.rawInput());
190+
phoneProto.putFields("input", input.build());
191+
}
192+
if (phone.defaultCountry() != null) {
193+
var defaultCountry = com.google.protobuf.Value.newBuilder().setStringValue(phone.defaultCountry());
194+
phoneProto.putFields("defaultCountry", defaultCountry.build());
195+
}
196+
protoValue.setStructValue(phoneProto);
197+
} else if (value instanceof GeoCoordinates geo) {
198+
var latitude = com.google.protobuf.Value.newBuilder().setNumberValue(geo.latitude());
199+
var longitude = com.google.protobuf.Value.newBuilder().setNumberValue(geo.longitude());
200+
protoValue.setStructValue(com.google.protobuf.Struct.newBuilder()
201+
.putFields("latitude", latitude.build())
202+
.putFields("longitude", longitude.build()));
184203
} else if (value instanceof List<?> v) {
185204
protoValue.setListValue(
186205
com.google.protobuf.ListValue.newBuilder()

src/main/java/io/weaviate/client6/v1/api/collections/query/QueryResponse.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import java.util.UUID;
77
import java.util.stream.Stream;
88

9+
import io.weaviate.client6.v1.api.collections.GeoCoordinates;
910
import io.weaviate.client6.v1.api.collections.ObjectMetadata;
11+
import io.weaviate.client6.v1.api.collections.PhoneNumber;
1012
import io.weaviate.client6.v1.api.collections.Vectors;
1113
import io.weaviate.client6.v1.api.collections.WeaviateObject;
1214
import io.weaviate.client6.v1.internal.DateUtil;
@@ -159,6 +161,21 @@ static <PropertiesT> void setProperty(String property, WeaviateProtoProperties.V
159161
builder.setOffsetDateTime(property, DateUtil.fromISO8601(value.getDateValue()));
160162
} else if (value.hasUuidValue()) {
161163
builder.setUuid(property, UUID.fromString(value.getUuidValue()));
164+
} else if (value.hasPhoneValue()) {
165+
var phone = value.getPhoneValue();
166+
builder.setPhoneNumber(property, new PhoneNumber(
167+
phone.getInput(),
168+
phone.getDefaultCountry(),
169+
Long.valueOf(phone.getCountryCode()).intValue(),
170+
phone.getInternationalFormatted(),
171+
Long.valueOf(phone.getNational()).intValue(),
172+
phone.getNationalFormatted(),
173+
phone.getValid()));
174+
} else if (value.hasGeoValue()) {
175+
var geo = value.getGeoValue();
176+
builder.setGeoCoordinates(property, new GeoCoordinates(
177+
geo.getLatitude(),
178+
geo.getLongitude()));
162179
} else if (value.hasListValue()) {
163180
var list = value.getListValue();
164181
if (list.hasTextValues()) {

src/main/java/io/weaviate/client6/v1/api/collections/query/Where.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -826,11 +826,11 @@ public String toString() {
826826
}
827827

828828
private static class GeoRangeOperand implements WhereOperand {
829-
private final Float lat;
830-
private final Float lon;
831-
private final Float distance;
829+
private final float lat;
830+
private final float lon;
831+
private final float distance;
832832

833-
private GeoRangeOperand(Float lat, Float lon, Float distance) {
833+
private GeoRangeOperand(float lat, float lon, float distance) {
834834
this.lat = lat;
835835
this.lon = lon;
836836
this.distance = distance;

src/main/java/io/weaviate/client6/v1/internal/orm/MapBuilder.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import java.util.Map;
77
import java.util.UUID;
88

9+
import io.weaviate.client6.v1.api.collections.GeoCoordinates;
10+
import io.weaviate.client6.v1.api.collections.PhoneNumber;
11+
912
public class MapBuilder implements PropertiesBuilder<Map<String, Object>> {
1013
private final Map<String, Object> properties = new HashMap<>();
1114

@@ -89,8 +92,18 @@ public void setNestedObjectArray(String property, List<? extends Object> value)
8992
properties.put(property, value);
9093
}
9194

95+
@Override
96+
public void setPhoneNumber(String property, PhoneNumber value) {
97+
properties.put(property, value);
98+
}
99+
100+
@Override
101+
public void setGeoCoordinates(String property, GeoCoordinates value) {
102+
properties.put(property, value);
103+
}
104+
92105
@Override
93106
public Map<String, Object> build() {
94-
return properties;
107+
return new HashMap<>(properties);
95108
}
96109
}

0 commit comments

Comments
 (0)