Search in sources :

Example 6 with MapResult

use of apoc.result.MapResult in project neo4j-apoc-procedures by neo4j-contrib.

the class Cypher method whenCase.

@Procedure("apoc.case")
@Description("apoc.case([condition, query, condition, query, ...], elseQuery:'', params:{}) yield value - given a list of conditional / read-only query pairs, executes the query associated with the first conditional evaluating to true (or the else query if none are true) with the given parameters")
public Stream<MapResult> whenCase(@Name("conditionals") List<Object> conditionals, @Name(value = "elseQuery", defaultValue = "") String elseQuery, @Name(value = "params", defaultValue = "") Map<String, Object> params) {
    if (params == null)
        params = Collections.emptyMap();
    if (conditionals.size() % 2 != 0) {
        throw new IllegalArgumentException("Conditionals must be an even-sized collection of boolean, query entries");
    }
    Iterator caseItr = conditionals.iterator();
    while (caseItr.hasNext()) {
        boolean condition = (Boolean) caseItr.next();
        String ifQuery = (String) caseItr.next();
        if (condition) {
            return db.execute(withParamMapping(ifQuery, params.keySet()), params).stream().map(MapResult::new);
        }
    }
    if (elseQuery.isEmpty()) {
        return Stream.of(new MapResult(Collections.emptyMap()));
    } else {
        return db.execute(withParamMapping(elseQuery, params.keySet()), params).stream().map(MapResult::new);
    }
}
Also used : MapResult(apoc.result.MapResult)

Example 7 with MapResult

use of apoc.result.MapResult in project neo4j-apoc-procedures by neo4j-contrib.

the class Cypher method mapParallel2.

@Procedure
@Description("apoc.cypher.mapParallel2(fragment, params, list-to-parallelize) yield value - executes fragment in parallel batches with the list segments being assigned to _")
public Stream<MapResult> mapParallel2(@Name("fragment") String fragment, @Name("params") Map<String, Object> params, @Name("list") List<Object> data, @Name("partitions") long partitions) {
    final String statement = withParamsAndIterator(fragment, params.keySet(), "_");
    db.execute("EXPLAIN " + statement).close();
    BlockingQueue<RowResult> queue = new ArrayBlockingQueue<>(100000);
    Stream<List<Object>> parallelPartitions = Util.partitionSubList(data, (int) (partitions <= 0 ? PARTITIONS : partitions), null);
    Util.inFuture(() -> {
        long total = parallelPartitions.map((List<Object> partition) -> {
            try {
                return executeStatement(queue, statement, parallelParams(params, "_", partition), false);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }).count();
        queue.put(RowResult.TOMBSTONE);
        return total;
    });
    return StreamSupport.stream(new QueueBasedSpliterator<>(queue, RowResult.TOMBSTONE, terminationGuard), true).map((rowResult) -> new MapResult(rowResult.result));
}
Also used : QueueBasedSpliterator(apoc.util.QueueBasedSpliterator) MapResult(apoc.result.MapResult) IOException(java.io.IOException) Collections.singletonList(java.util.Collections.singletonList) Collectors.toList(java.util.stream.Collectors.toList)

Example 8 with MapResult

use of apoc.result.MapResult in project neo4j-apoc-procedures by neo4j-contrib.

the class Timeboxed method runTimeboxed.

@Procedure
@Description("apoc.cypher.runTimeboxed('cypherStatement',{params}, timeout) - abort statement after timeout ms if not finished")
public Stream<MapResult> runTimeboxed(@Name("cypher") String cypher, @Name("params") Map<String, Object> params, @Name("timeout") long timeout) {
    final BlockingQueue<Map<String, Object>> queue = new ArrayBlockingQueue<>(100);
    final AtomicReference<Transaction> txAtomic = new AtomicReference<>();
    // run query to be timeboxed in a separate thread to enable proper tx termination
    // if we'd run this in current thread, a tx.terminate would kill the transaction the procedure call uses itself.
    Pools.DEFAULT.submit(() -> {
        try (Transaction tx = db.beginTx()) {
            txAtomic.set(tx);
            Result result = db.execute(cypher, params == null ? Collections.EMPTY_MAP : params);
            while (result.hasNext()) {
                final Map<String, Object> map = result.next();
                offerToQueue(queue, map, timeout);
            }
            offerToQueue(queue, POISON, timeout);
            tx.success();
        } catch (TransactionTerminatedException e) {
            log.warn("query " + cypher + " has been terminated");
        } finally {
            txAtomic.set(null);
        }
    });
    // 
    Pools.SCHEDULED.schedule(() -> {
        Transaction tx = txAtomic.get();
        if (tx == null) {
            log.info("tx is null, either the other transaction finished gracefully or has not yet been start.");
        } else {
            tx.terminate();
            offerToQueue(queue, POISON, timeout);
            log.warn("terminating transaction, putting POISON onto queue");
        }
    }, timeout, MILLISECONDS);
    // consume the blocking queue using a custom iterator finishing upon POISON
    Iterator<Map<String, Object>> queueConsumer = new Iterator<Map<String, Object>>() {

        Map<String, Object> nextElement = null;

        boolean hasFinished = false;

        @Override
        public boolean hasNext() {
            if (hasFinished) {
                return false;
            } else {
                try {
                    nextElement = queue.poll(timeout, MILLISECONDS);
                    if (nextElement == null) {
                        log.warn("couldn't grab queue element, aborting - this should never happen");
                        hasFinished = true;
                    } else {
                        hasFinished = POISON.equals(nextElement);
                    }
                    return !hasFinished;
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        @Override
        public Map<String, Object> next() {
            return nextElement;
        }
    };
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(queueConsumer, Spliterator.ORDERED), false).map(MapResult::new);
}
Also used : TransactionTerminatedException(org.neo4j.graphdb.TransactionTerminatedException) AtomicReference(java.util.concurrent.atomic.AtomicReference) MapResult(apoc.result.MapResult) Result(org.neo4j.graphdb.Result) MapResult(apoc.result.MapResult) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) Transaction(org.neo4j.graphdb.Transaction)

Aggregations

MapResult (apoc.result.MapResult)8 IOException (java.io.IOException)3 ObjectResult (apoc.result.ObjectResult)2 JsonUtil (apoc.util.JsonUtil)2 java.util (java.util)2 XMLStreamException (javax.xml.stream.XMLStreamException)2 Description (org.neo4j.procedure.Description)2 ListResult (apoc.result.ListResult)1 StringResult (apoc.result.StringResult)1 MapUtil (apoc.util.MapUtil)1 QueueBasedSpliterator (apoc.util.QueueBasedSpliterator)1 Util (apoc.util.Util)1 JsonPath (com.jayway.jsonpath.JsonPath)1 java.io (java.io)1 FileNotFoundException (java.io.FileNotFoundException)1 URI (java.net.URI)1 Collections.singletonList (java.util.Collections.singletonList)1 Collections.singletonMap (java.util.Collections.singletonMap)1 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1