Browse Source

Fix a regression for parsing JSON field values returned by search/query (#1352)

Signed-off-by: yhmo <yihua.mo@zilliz.com>
groot 1 month ago
parent
commit
fdf367abbe

+ 7 - 1
examples/src/main/java/io/milvus/v1/BulkWriterExample.java

@@ -169,6 +169,8 @@ public class BulkWriterExample {
         exampleBulkWriter.createConnection();
 
         List<BulkFileType> fileTypes = Lists.newArrayList(
+                BulkFileType.JSON,
+                BulkFileType.CSV,
                 BulkFileType.PARQUET
         );
 
@@ -387,7 +389,11 @@ public class BulkWriterExample {
                 rowObject.addProperty("float", i / 3);
                 rowObject.addProperty("double", i / 7);
                 rowObject.addProperty("varchar", "varchar_" + i);
-                rowObject.addProperty("json", String.format("{\"dummy\": %s, \"ok\": \"name_%s\"}", i, i));
+
+                // Note: for JSON field, use gson.fromJson() to construct a real JsonObject
+                // don't use rowObject.addProperty("json", jsonContent) since the value is treated as a string, not a JsonObject
+                String jsonContent = String.format("{\"dummy\": %s, \"ok\": \"name_%s\"}", i, i);
+                rowObject.add("json", GSON_INSTANCE.fromJson(jsonContent, JsonElement.class));
 
                 // vector field
                 rowObject.add("float_vector", GSON_INSTANCE.toJsonTree(CommonUtils.generateFloatVector(DIM)));

+ 2 - 0
examples/src/main/java/io/milvus/v1/JsonFieldExample.java

@@ -130,6 +130,8 @@ public class JsonFieldExample {
             row.addProperty(ID_FIELD, i);
             row.add(VECTOR_FIELD, gson.toJsonTree(CommonUtils.generateFloatVector(VECTOR_DIM)));
 
+            // Note: for JSON field, always construct a real JsonObject
+            // don't use row.addProperty(JSON_FIELD, strContent) since the value is treated as a string, not a JsonObject
             JsonObject metadata = new JsonObject();
             metadata.addProperty("path", String.format("\\root/abc/path%d", i));
             metadata.addProperty("size", i);

+ 7 - 3
examples/src/main/java/io/milvus/v2/BulkWriterExample.java

@@ -441,7 +441,11 @@ public class BulkWriterExample {
                 rowObject.addProperty("double", (Number) row.get("double"));
             }
             rowObject.addProperty("varchar", row.get("varchar") == null ? null : (String) row.get("varchar"));
-            rowObject.addProperty("json", row.get("json") == null ? null : (String) row.get("json"));
+
+            // Note: for JSON field, use gson.fromJson() to construct a real JsonObject
+            // don't use rowObject.addProperty("json", jsonContent) since the value is treated as a string, not a JsonObject
+            Object jsonContent = row.get("json");
+            rowObject.add("json", jsonContent == null ? null : GSON_INSTANCE.fromJson((String)jsonContent, JsonElement.class));
 
             // vector field
             rowObject.add("float_vector", GSON_INSTANCE.toJsonTree(row.get("float_vector")));
@@ -720,8 +724,8 @@ public class BulkWriterExample {
         } else if (fetchedValue instanceof Double) {
             matched = Math.abs((Double)fetchedValue - (Double)expectedValue) < 1e-8;
         } else if (fetchedValue instanceof JsonElement) {
-            String ss = fetchedValue.toString();
-            matched = ss.equals(((String)expectedValue).replaceAll("\\s", "")); // compare ignore space
+            JsonElement expectedJson = GSON_INSTANCE.fromJson((String)expectedValue, JsonElement.class);
+            matched = fetchedValue.equals(expectedJson);
         } else if (fetchedValue instanceof ByteBuffer) {
             byte[] bb = ((ByteBuffer)fetchedValue).array();
             matched = Arrays.equals(bb, (byte[])expectedValue);

+ 2 - 0
examples/src/main/java/io/milvus/v2/JsonFieldExample.java

@@ -109,6 +109,8 @@ public class JsonFieldExample {
             row.addProperty(ID_FIELD, i);
             row.add(VECTOR_FIELD, gson.toJsonTree(CommonUtils.generateFloatVector(VECTOR_DIM)));
 
+            // Note: for JSON field, always construct a real JsonObject
+            // don't use row.addProperty(JSON_FIELD, strContent) since the value is treated as a string, not a JsonObject
             JsonObject metadata = new JsonObject();
             metadata.addProperty("path", String.format("\\root/abc/path%d", i));
             metadata.addProperty("size", i);

+ 1 - 7
sdk-core/src/main/java/io/milvus/response/FieldDataWrapper.java

@@ -386,13 +386,7 @@ public class FieldDataWrapper {
 
     public static JsonElement ParseJSONObject(Object object) {
         if (object instanceof String) {
-            // For JSON field, milvus server returns a string value with redundant escape character
-            // and the string value is wrapped by a pair of quotations, the JsonParser.parseString() will
-            // parse it as a JsonPrimitive, not a JsonObject.
-            // Here we convert the string value to a valid JSON string so that
-            // JsonParser.parseString() can parse it to be JsonObject.
-            String ss = ((String)object).replace("\\\"", "\"").replaceAll("^\"|\"$", "");
-            return JsonParser.parseString(ss);
+            return JsonParser.parseString((String)object);
         } else if (object instanceof byte[]) {
             return JsonParser.parseString(new String((byte[]) object));
         } else {