apoc.convert.Json Maven / Gradle / Ivy
package apoc.convert;
import apoc.meta.Types;
import apoc.result.MapResult;
import apoc.util.JsonUtil;
import apoc.util.Util;
import org.neo4j.graphdb.Entity;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.Relationship;
import org.neo4j.procedure.*;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static apoc.util.Util.labelStrings;
import static apoc.util.Util.map;
public class Json {
// visible for testing
public static String NODE = "node";
public static String RELATIONSHIP = "relationship";
public static Object writeJsonResult(Object value) {
Types type = Types.of(value);
switch (type) {
case NODE:
return nodeToMap((Node) value);
case RELATIONSHIP:
return relToMap((Relationship) value);
case PATH:
return writeJsonResult(StreamSupport.stream(((Path)value).spliterator(),false)
.map(i-> i instanceof Node ? nodeToMap((Node) i) : relToMap((Relationship) i))
.collect(Collectors.toList()));
case LIST:
return ConvertUtils.convertToList(value).stream().map(Json::writeJsonResult).collect(Collectors.toList());
case MAP:
return ((Map) value).entrySet()
.stream()
.collect(HashMap::new, // workaround for https://bugs.openjdk.java.net/browse/JDK-8148463
(mapAccumulator, entry) -> mapAccumulator.put(entry.getKey(), writeJsonResult(entry.getValue())),
HashMap::putAll);
default:
return value;
}
}
private static Map relToMap(Relationship rel) {
Map mapRel = map(
"id", String.valueOf(rel.getId()),
"type", RELATIONSHIP,
"label", rel.getType().toString(),
"start", nodeToMap(rel.getStartNode()),
"end", nodeToMap(rel.getEndNode()));
return mapWithOptionalProps(mapRel, rel.getAllProperties());
}
private static Map nodeToMap(Node node) {
Map mapNode = map("id", String.valueOf(node.getId()));
mapNode.put("type", NODE);
if (node.getLabels().iterator().hasNext()) {
mapNode.put("labels", labelStrings(node));
}
return mapWithOptionalProps(mapNode, node.getAllProperties());
}
private static Map mapWithOptionalProps(Map mapEntity, Map props) {
if (!props.isEmpty()) {
mapEntity.put("properties", props);
}
return mapEntity;
}
@Context
public org.neo4j.graphdb.GraphDatabaseService db;
@UserFunction("apoc.json.path")
@Description("Returns the given JSON path.")
public Object path(@Name("json") String json, @Name(value = "path",defaultValue = "$") String path, @Name(value = "pathOptions", defaultValue = "null") List pathOptions) {
return JsonUtil.parse(json, path, Object.class, pathOptions);
}
@UserFunction("apoc.convert.toJson")
@Description("Serializes the given JSON value.")
public String toJson(@Name("value") Object value) {
try {
return JsonUtil.OBJECT_MAPPER.writeValueAsString(writeJsonResult(value));
} catch (IOException e) {
throw new RuntimeException("Can't convert " + value + " to json", e);
}
}
@Procedure(name = "apoc.convert.setJsonProperty", mode = Mode.WRITE)
@Description("Serializes the given JSON object and sets it as a property on the given node.")
public void setJsonProperty(@Name("node") Node node, @Name("key") String key, @Name("value") Object value) {
try {
node.setProperty(key, JsonUtil.OBJECT_MAPPER.writeValueAsString(value));
} catch (IOException e) {
throw new RuntimeException("Can't convert " + value + " to json", e);
}
}
@UserFunction("apoc.convert.getJsonProperty")
@Description("Converts a serialized JSON object from the property of the given node into the equivalent Cypher structure (e.g. map, list).")
public Object getJsonProperty(@Name("node") Node node, @Name("key") String key,@Name(value = "path",defaultValue = "") String path, @Name(value = "pathOptions", defaultValue = "null") List pathOptions) {
String value = (String) node.getProperty(key, null);
return JsonUtil.parse(value, path, Object.class, pathOptions);
}
@UserFunction("apoc.convert.getJsonPropertyMap")
@Description("Converts a serialized JSON object from the property of the given node into a Cypher map.")
public Map getJsonPropertyMap(@Name("node") Node node, @Name("key") String key,@Name(value = "path",defaultValue = "") String path, @Name(value = "pathOptions", defaultValue = "null") List pathOptions) {
String value = (String) node.getProperty(key, null);
return JsonUtil.parse(value, path, Map.class, pathOptions);
}
@UserFunction("apoc.convert.fromJsonMap")
@Description("Converts the given JSON map into a Cypher map.")
public Map fromJsonMap(@Name("map") String value,@Name(value = "path",defaultValue = "") String path, @Name(value = "pathOptions", defaultValue = "null") List pathOptions) {
return JsonUtil.parse(value, path, Map.class, pathOptions);
}
@UserFunction("apoc.convert.fromJsonList")
@Description("Converts the given JSON list into a Cypher list.")
public List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy