Search in sources :

Example 1 with Description

use of apoc.Description in project neo4j-apoc-procedures by neo4j-contrib.

the class Grouping method group.

@Procedure
@Description("Group all nodes and their relationships by given keys, create virtual nodes and relationships for the summary information, you can provide an aggregations map [{kids:'sum',age:['min','max','avg'],gender:'collect'},{`*`,'count'}]")
public Stream<GraphResult> group(@Name("labels") List<String> labels, @Name("groupByProperties") List<String> groupByProperties, @Name(value = "aggregations", defaultValue = "[{\"*\":\"count\"},{\"*\":\"count\"}]") List<Map<String, Object>> aggregations) {
    String[] keys = groupByProperties.toArray(new String[groupByProperties.size()]);
    Map<String, List<String>> nodeAggNames = (aggregations.size() > 0) ? toStringListMap(aggregations.get(0)) : emptyMap();
    String[] nodeAggKeys = keyArray(nodeAggNames, ASTERISK);
    Map<String, List<String>> relAggNames = (aggregations.size() > 1) ? toStringListMap(aggregations.get(1)) : emptyMap();
    String[] relAggKeys = keyArray(relAggNames, ASTERISK);
    Map<NodeKey, Set<Node>> grouped = new ConcurrentHashMap<>();
    Map<NodeKey, Node> virtualNodes = new ConcurrentHashMap<>();
    Map<RelKey, Relationship> virtualRels = new ConcurrentHashMap<>();
    List<Future> futures = new ArrayList<>(1000);
    ExecutorService pool = Pools.DEFAULT;
    for (String labelName : labels) {
        Label label = Label.label(labelName);
        Label[] singleLabel = { label };
        try (ResourceIterator<Node> nodes = (labelName.equals(ASTERISK)) ? db.getAllNodes().iterator() : db.findNodes(label)) {
            while (nodes.hasNext()) {
                List<Node> batch = Util.take(nodes, BATCHSIZE);
                futures.add(Util.inTxFuture(pool, db, () -> {
                    try {
                        for (Node node : batch) {
                            NodeKey key = keyFor(node, labelName, keys);
                            grouped.compute(key, (k, v) -> {
                                if (v == null)
                                    v = new HashSet<>();
                                v.add(node);
                                return v;
                            });
                            virtualNodes.compute(key, (k, v) -> {
                                if (v == null) {
                                    v = new VirtualNode(singleLabel, propertiesFor(node, keys), db);
                                }
                                Node vn = v;
                                if (!nodeAggNames.isEmpty()) {
                                    aggregate(vn, nodeAggNames, nodeAggKeys.length > 0 ? node.getProperties(nodeAggKeys) : Collections.emptyMap());
                                }
                                return vn;
                            });
                        }
                    } catch (Exception e) {
                        log.debug("Error grouping nodes", e);
                    }
                    return null;
                }));
                Util.removeFinished(futures);
            }
        }
    }
    Util.waitForFutures(futures);
    futures.clear();
    Iterator<Map.Entry<NodeKey, Set<Node>>> entries = grouped.entrySet().iterator();
    int size = 0;
    List<Map.Entry<NodeKey, Set<Node>>> batch = new ArrayList<>();
    while (entries.hasNext()) {
        Map.Entry<NodeKey, Set<Node>> outerEntry = entries.next();
        batch.add(outerEntry);
        size += outerEntry.getValue().size();
        if (size > BATCHSIZE || !entries.hasNext()) {
            ArrayList<Map.Entry<NodeKey, Set<Node>>> submitted = new ArrayList<>(batch);
            batch.clear();
            size = 0;
            futures.add(Util.inTxFuture(pool, db, () -> {
                try {
                    for (Map.Entry<NodeKey, Set<Node>> entry : submitted) {
                        for (Node node : entry.getValue()) {
                            NodeKey startKey = entry.getKey();
                            Node v1 = virtualNodes.get(startKey);
                            for (Relationship rel : node.getRelationships(Direction.OUTGOING)) {
                                Node endNode = rel.getEndNode();
                                for (NodeKey endKey : keysFor(endNode, labels, keys)) {
                                    Node v2 = virtualNodes.get(endKey);
                                    if (v2 == null)
                                        continue;
                                    virtualRels.compute(new RelKey(startKey, endKey, rel), (rk, vRel) -> {
                                        if (vRel == null)
                                            vRel = v1.createRelationshipTo(v2, rel.getType());
                                        if (!relAggNames.isEmpty()) {
                                            aggregate(vRel, relAggNames, relAggKeys.length > 0 ? rel.getProperties(relAggKeys) : Collections.emptyMap());
                                        }
                                        return vRel;
                                    });
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    log.debug("Error grouping relationships", e);
                }
                return null;
            }));
            Util.removeFinished(futures);
        }
    }
    Util.waitForFutures(futures);
    return fixAggregates(virtualNodes.values()).stream().map(n -> new GraphResult(singletonList(n), fixAggregates(Iterables.asList(n.getRelationships()))));
}
Also used : Collections.emptyMap(java.util.Collections.emptyMap) java.util(java.util) GraphResult(apoc.result.GraphResult) Log(org.neo4j.logging.Log) VirtualNode(apoc.result.VirtualNode) Context(org.neo4j.procedure.Context) Pools(apoc.Pools) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Collectors(java.util.stream.Collectors) Collections.singletonList(java.util.Collections.singletonList) Future(java.util.concurrent.Future) Iterables(org.neo4j.helpers.collection.Iterables) Stream(java.util.stream.Stream) Description(apoc.Description) org.neo4j.graphdb(org.neo4j.graphdb) Name(org.neo4j.procedure.Name) Util(apoc.util.Util) Procedure(org.neo4j.procedure.Procedure) ExecutorService(java.util.concurrent.ExecutorService) VirtualNode(apoc.result.VirtualNode) VirtualNode(apoc.result.VirtualNode) Collections.singletonList(java.util.Collections.singletonList) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) GraphResult(apoc.result.GraphResult) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) Collections.emptyMap(java.util.Collections.emptyMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Description(apoc.Description) Procedure(org.neo4j.procedure.Procedure)

Example 2 with Description

use of apoc.Description in project neo4j-apoc-procedures by neo4j-contrib.

the class Bolt method load.

@Procedure()
@Description("apoc.bolt.load(url-or-key, statement, params, config) - access to other databases via bolt for read")
public Stream<RowResult> load(@Name("url") String url, @Name("statement") String statement, @Name(value = "params", defaultValue = "{}") Map<String, Object> params, @Name(value = "config", defaultValue = "{}") Map<String, Object> config) throws URISyntaxException {
    if (params == null)
        params = Collections.emptyMap();
    if (config == null)
        config = Collections.emptyMap();
    boolean virtual = (boolean) config.getOrDefault("virtual", false);
    boolean addStatistics = (boolean) config.getOrDefault("statistics", false);
    boolean readOnly = (boolean) config.getOrDefault("readOnly", true);
    Config driverConfig = toDriverConfig(config.getOrDefault("driverConfig", map()));
    UriResolver uri = new UriResolver(url, "bolt");
    uri.initialize();
    try (Driver driver = GraphDatabase.driver(uri.getConfiguredUri(), uri.getToken(), driverConfig);
        Session session = driver.session()) {
        if (addStatistics)
            return Stream.of(new RowResult(toMap(runStatement(statement, session, params, readOnly).summary().counters())));
        else
            return getRowResultStream(virtual, session, params, statement, readOnly);
    } catch (Exception e) {
        throw new RuntimeException("It's not possible to create a connection due to: " + e.getMessage());
    }
}
Also used : RowResult(apoc.result.RowResult) UriResolver(apoc.util.UriResolver) URISyntaxException(java.net.URISyntaxException) Description(apoc.Description) Procedure(org.neo4j.procedure.Procedure)

Example 3 with Description

use of apoc.Description in project neo4j-apoc-procedures by neo4j-contrib.

the class Cluster method graph.

@Procedure
@Description("apoc.cluster.graph - visually displays the servers participating in the Causal Cluster, their " + "roles, and which server in the cluster you are connected to.")
public Stream<GraphResult> graph() {
    Result execute = db.execute("CALL dbms.cluster.overview()");
    List<Node> servers = new LinkedList<>();
    List<Relationship> relationships = new LinkedList<>();
    while (execute.hasNext()) {
        Map<String, Object> next = execute.next();
        String role = (String) next.get("role");
        String id = (String) next.get("id");
        Label roleLabel = Label.label(role);
        String[] addresses = ((List<String>) next.get("addresses")).toArray(new String[0]);
        Map<String, Object> properties = new HashMap<>();
        properties.put("name", shortName.get(role));
        properties.put("title", role);
        properties.put(boltAddressKey, addresses[0]);
        properties.put("http_address", addresses[1]);
        properties.put("cluster_id", id);
        Node server = new VirtualNode(new Label[] { roleLabel }, properties, db);
        servers.add(server);
    }
    Optional<Node> leaderNode = getLeaderNode(servers);
    if (leaderNode.isPresent()) {
        for (Node server : servers) {
            if (server.hasLabel(Label.label("FOLLOWER"))) {
                VirtualRelationship follows = new VirtualRelationship(server, leaderNode.get(), RelationshipType.withName("FOLLOWS"));
                relationships.add(follows);
            }
        }
    }
    VirtualNode client = new VirtualNode(new Label[] { Label.label("CLIENT") }, singletonMap("name", "Client"), db);
    Optional<Relationship> clientConnection = determineClientConnection(servers, client);
    if (clientConnection.isPresent()) {
        servers.add(client);
        relationships.add(clientConnection.get());
    }
    GraphResult graphResult = new GraphResult(servers, relationships);
    return Stream.of(graphResult);
}
Also used : HashMap(java.util.HashMap) GraphResult(apoc.result.GraphResult) VirtualNode(apoc.result.VirtualNode) VirtualNode(apoc.result.VirtualNode) Node(org.neo4j.graphdb.Node) Label(org.neo4j.graphdb.Label) LinkedList(java.util.LinkedList) GraphResult(apoc.result.GraphResult) Result(org.neo4j.graphdb.Result) VirtualRelationship(apoc.result.VirtualRelationship) VirtualRelationship(apoc.result.VirtualRelationship) Relationship(org.neo4j.graphdb.Relationship) LinkedList(java.util.LinkedList) List(java.util.List) Description(apoc.Description) Procedure(org.neo4j.procedure.Procedure)

Example 4 with Description

use of apoc.Description in project neo4j-apoc-procedures by neo4j-contrib.

the class ExportCSV method graph.

@Procedure
@Description("apoc.export.csv.graph(graph,file,config) - exports given graph object as csv to the provided file")
public Stream<ProgressInfo> graph(@Name("graph") Map<String, Object> graph, @Name("file") String fileName, @Name("config") Map<String, Object> config) throws Exception {
    Collection<Node> nodes = (Collection<Node>) graph.get("nodes");
    Collection<Relationship> rels = (Collection<Relationship>) graph.get("relationships");
    String source = String.format("graph: nodes(%d), rels(%d)", nodes.size(), rels.size());
    return exportCsv(fileName, source, new NodesAndRelsSubGraph(db, nodes, rels), config);
}
Also used : Node(org.neo4j.graphdb.Node) Relationship(org.neo4j.graphdb.Relationship) NodesAndRelsSubGraph(apoc.export.util.NodesAndRelsSubGraph) Collection(java.util.Collection) Description(apoc.Description) Procedure(org.neo4j.procedure.Procedure)

Example 5 with Description

use of apoc.Description in project neo4j-apoc-procedures by neo4j-contrib.

the class ExportCSV method query.

@Procedure
@Description("apoc.export.csv.query(query,file,{config,...,params:{params}}) - exports results from the cypher statement as csv to the provided file")
public Stream<ProgressInfo> query(@Name("query") String query, @Name("file") String fileName, @Name("config") Map<String, Object> config) throws Exception {
    Map<String, Object> params = config == null ? Collections.emptyMap() : (Map<String, Object>) config.getOrDefault("params", Collections.emptyMap());
    Result result = db.execute(query, params);
    String source = String.format("statement: cols(%d)", result.columns().size());
    return exportCsv(fileName, source, result, config);
}
Also used : Result(org.neo4j.graphdb.Result) Description(apoc.Description) Procedure(org.neo4j.procedure.Procedure)

Aggregations

Description (apoc.Description)6 Procedure (org.neo4j.procedure.Procedure)5 GraphResult (apoc.result.GraphResult)2 VirtualNode (apoc.result.VirtualNode)2 Util (apoc.util.Util)2 java.util (java.util)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Stream (java.util.stream.Stream)2 org.neo4j.graphdb (org.neo4j.graphdb)2 Node (org.neo4j.graphdb.Node)2 Relationship (org.neo4j.graphdb.Relationship)2 Result (org.neo4j.graphdb.Result)2 Log (org.neo4j.logging.Log)2 ApocConfiguration (apoc.ApocConfiguration)1 Pools (apoc.Pools)1 SetBackedList (apoc.coll.SetBackedList)1 NodesAndRelsSubGraph (apoc.export.util.NodesAndRelsSubGraph)1 RowResult (apoc.result.RowResult)1 VirtualRelationship (apoc.result.VirtualRelationship)1 UriResolver (apoc.util.UriResolver)1