Graphs { @Description("apoc.graph.validateDocument({json}, {config}) yield row - validates the json, return the result of the validation") @Procedure(mode = Mode.READ) public Stream<RowResult> validateDocument(@Name("json") Object document, @Name(value = "config", defaultValue = "{}") Map<String,Object> config) { GraphsConfig graphConfig = new GraphsConfig(config); DocumentToGraph documentToGraph = new DocumentToGraph(tx, graphConfig); Map<Long, List<String>> dups = documentToGraph.validateDocument(document); return dups.entrySet().stream() .map(e -> new RowResult(Util.map("index", e.getKey(), "message", String.join(StringUtils.LF, e.getValue())))); }  @Description("apoc.graph.fromData([nodes],[relationships],'name',{properties}) | creates a virtual graph object for later processing") @Procedure Stream<VirtualGraph> fromData(@Name("nodes") List<Node> nodes, @Name("relationships") List<Relationship> relationships, @Name("name") String name, @Name("properties") Map<String,Object> properties); @Description("apoc.graph.from(data,'name',{properties}) | creates a virtual graph object for later processing it tries its best to extract the graph information from the data you pass in") @Procedure Stream<VirtualGraph> from(@Name("data") Object data, @Name("name") String name, @Name("properties") Map<String,Object> properties); static boolean extract(Object data, Set<Node> nodes, Set<Relationship> rels); @Description("apoc.graph.fromPaths(path,'name',{properties}) - creates a virtual graph object for later processing") @Procedure Stream<VirtualGraph> fromPath(@Name("path") Path paths, @Name("name") String name, @Name("properties") Map<String,Object> properties); @Description("apoc.graph.fromPaths([paths],'name',{properties}) - creates a virtual graph object for later processing") @Procedure Stream<VirtualGraph> fromPaths(@Name("paths") List<Path> paths, @Name("name") String name, @Name("properties") Map<String,Object> properties); @Description("apoc.graph.fromDB('name',{properties}) - creates a virtual graph object for later processing") @Procedure Stream<VirtualGraph> fromDB(@Name("name") String name, @Name("properties") Map<String,Object> properties); @Description("apoc.graph.fromCypher('kernelTransaction',{params},'name',{properties}) - creates a virtual graph object for later processing") @Procedure Stream<VirtualGraph> fromCypher(@Name("kernelTransaction") String statement,  @Name("params") Map<String,Object> params,@Name("name") String name,  @Name("properties") Map<String,Object> properties); @Description("apoc.graph.fromDocument({json}, {config}) yield graph - transform JSON documents into graph structures") @Procedure(mode = Mode.WRITE) Stream<VirtualGraph> fromDocument(@Name("json") Object document, @Name(value = "config", defaultValue = "{}") Map<String,Object> config); @Description("apoc.graph.validateDocument({json}, {config}) yield row - validates the json, return the result of the validation") @Procedure(mode = Mode.READ) Stream<RowResult> validateDocument(@Name("json") Object document, @Name(value = "config", defaultValue = "{}") Map<String,Object> config); @Context
    public Transaction tx; }
@Test public void testValidateDocument() throws Exception { List<Object> list = Arrays.asList(Util.map("type", "artist", "name", "Daft Punk"), Util.map("id", 1, "type", "artist", "name", "Daft Punk"), Util.map("id", 1, "name", "Daft Punk"), Util.map("name", "Daft Punk")); TestUtil.testResult(db, "CALL apoc.graph.validateDocument($json, $config) yield row", Util.map("json", JsonUtil.OBJECT_MAPPER.writeValueAsString(list), "config", Util.map("generateId", false, "defaultLabel", "")), result -> { Map<String, Object> row = (Map<String, Object>) result.next().get("row"); assertEquals(0L, row.get("index")); assertEquals("The object `{\"type\":\"artist\",\"name\":\"Daft Punk\"}` must have `id` as id-field name", row.get("message")); row = (Map<String, Object>) result.next().get("row"); assertEquals(2L, row.get("index")); assertEquals("The object `{\"id\":1,\"name\":\"Daft Punk\"}` must have `type` as label-field name", row.get("message")); row = (Map<String, Object>) result.next().get("row"); assertEquals(3L, row.get("index")); assertEquals("The object `{\"name\":\"Daft Punk\"}` must have `id` as id-field name and `type` as label-field name", row.get("message")); assertFalse("should not have next", result.hasNext()); }); }