apoc.graph.Graphs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of apoc-core Show documentation
Show all versions of apoc-core Show documentation
Core package for Neo4j Procedures
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package apoc.graph;
import static apoc.graph.GraphsUtils.extract;
import apoc.cypher.CypherUtils;
import apoc.graph.document.builder.DocumentToGraph;
import apoc.graph.util.GraphsConfig;
import apoc.result.RowResult;
import apoc.result.VirtualGraph;
import apoc.util.Util;
import apoc.util.collection.Iterables;
import java.util.*;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.Transaction;
import org.neo4j.procedure.*;
/**
* @author mh
* @since 27.05.16
*/
public class Graphs {
@Context
public Transaction tx;
@Procedure("apoc.graph.fromData")
@Description(
"Generates a virtual sub-graph by extracting all of the `NODE` and `RELATIONSHIP` values from the given data.")
public Stream fromData(
@Name(value = "nodes", description = "The nodes to include in the resulting graph.") List nodes,
@Name(value = "rels", description = "The relationship to include in the resulting graph.")
List relationships,
@Name(value = "name", description = "The name of the resulting graph.") String name,
@Name(value = "props", description = "The properties to include in the resulting graph.")
Map properties) {
return Stream.of(new VirtualGraph(name, nodes, relationships, properties));
}
@Procedure("apoc.graph.from")
@Description(
"Generates a virtual sub-graph by extracting all of the `NODE` and `RELATIONSHIP` values from the given data.")
public Stream from(
@Name(
value = "data",
description =
"An object to extract nodes and relationships from. It can be of type; NODE | RELATIONSHIP | PATH | LIST.")
Object data,
@Name(value = "name", description = "The name of the resulting graph.") String name,
@Name(value = "props", description = "The properties to be present in the resulting graph.")
Map properties) {
Set nodes = new HashSet<>(1000);
Set rels = new HashSet<>(10000);
extract(data, nodes, rels);
return Stream.of(new VirtualGraph(name, nodes, rels, properties));
}
@Procedure("apoc.graph.fromPath")
@Description(
"Generates a virtual sub-graph by extracting all of the `NODE` and `RELATIONSHIP` values from the data returned by the given `PATH`.")
public Stream fromPath(
@Name(value = "path", description = "A path to extract the nodes and relationships from.") Path paths,
@Name(value = "name", description = "The name to give the resulting graph.") String name,
@Name(value = "props", description = "The properties to include in the resulting graph.")
Map properties) {
return Stream.of(new VirtualGraph(name, paths.nodes(), paths.relationships(), properties));
}
@Procedure("apoc.graph.fromPaths")
@Description(
"Generates a virtual sub-graph by extracting all of the `NODE` and `RELATIONSHIP` values from the data returned by the given `PATH` values.")
public Stream fromPaths(
@Name(value = "paths", description = "A list of paths to extract nodes and relationships from.")
List paths,
@Name(value = "name", description = "The name of the resulting graph.") String name,
@Name(value = "props", description = "The properties to include in the resulting graph.")
Map properties) {
List nodes = new ArrayList<>(1000);
List rels = new ArrayList<>(1000);
for (Path path : paths) {
Iterables.addAll(nodes, path.nodes());
Iterables.addAll(rels, path.relationships());
}
return Stream.of(new VirtualGraph(name, nodes, rels, properties));
}
@Procedure("apoc.graph.fromDB")
@Description(
"Generates a virtual sub-graph by extracting all of the `NODE` and `RELATIONSHIP` values from the data returned by the given database.")
public Stream fromDB(
@Name(value = "name", description = "The name of the resulting graph.") String name,
@Name(value = "props", description = "The properties to be present in the resulting graph.")
Map properties) {
return Stream.of(new VirtualGraph(name, tx.getAllNodes(), tx.getAllRelationships(), properties));
}
@NotThreadSafe
@Procedure("apoc.graph.fromCypher")
@Description(
"Generates a virtual sub-graph by extracting all of the `NODE` and `RELATIONSHIP` values from the data returned by the given Cypher statement.")
public Stream fromCypher(
@Name(value = "statement", description = "The Cypher statement to create the graph from.") String statement,
@Name(value = "params", description = "The parameters for the given Cypher statement.")
Map params,
@Name(value = "name", description = "The name of the resulting graph.") String name,
@Name(value = "props", description = "The properties to include in the resulting graph.")
Map properties) {
params = params == null ? Collections.emptyMap() : params;
Set nodes = new HashSet<>(1000);
Set rels = new HashSet<>(1000);
Map props = new HashMap<>(properties);
tx.execute(CypherUtils.withParamMapping(statement, params.keySet()), params).stream()
.forEach(row -> {
row.forEach((k, v) -> {
if (!extract(v, nodes, rels)) {
props.put(k, v);
}
});
});
return Stream.of(new VirtualGraph(name, nodes, rels, props));
}
@Procedure(name = "apoc.graph.fromDocument", mode = Mode.WRITE)
@Description(
"Generates a virtual sub-graph by extracting all of the `NODE` and `RELATIONSHIP` values from the data returned by the given JSON file.")
public Stream fromDocument(
@Name(value = "json", description = "A JSON object to generate a graph from.") Object document,
@Name(
value = "config",
defaultValue = "{}",
description =
"""
{
write = false :: BOOLEAN,
labelField = 'type' :: STRING.
idField = 'id' :: STRING,
generateID = true :: BOOLEAN,
defaultLabel = '' :: STRING,
skipValidation = false :: BOOLEAN,
mappings = {} :: MAP
}
""")
Map config) {
DocumentToGraph documentToGraph = new DocumentToGraph(tx, new GraphsConfig(config));
return Stream.of(documentToGraph.create(document));
}
@Procedure(name = "apoc.graph.validateDocument", mode = Mode.READ)
@Description("Validates the JSON file and returns the result of the validation.")
public Stream validateDocument(
@Name(value = "json", description = "The JSON object to validate.") Object document,
@Name(
value = "config",
defaultValue = "{}",
description =
"""
{
write = false :: BOOLEAN,
labelField = 'type' :: STRING.
idField = 'id' :: STRING,
generateID = true :: BOOLEAN,
defaultLabel = '' :: STRING,
skipValidation = false :: BOOLEAN,
mappings = {} :: MAP
}
""")
Map config) {
GraphsConfig graphConfig = new GraphsConfig(config);
DocumentToGraph documentToGraph = new DocumentToGraph(tx, graphConfig);
Map> dups = documentToGraph.validateDocument(document);
return dups.entrySet().stream()
.map(e -> new RowResult(
Util.map("index", e.getKey(), "message", String.join(StringUtils.LF, e.getValue()))));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy