質問

My question is this: how can I read multiple ResourceIterator objects coming back from a query, one "row" at a time?

I have a series of queries that return multiple columns; I'm trying to write a generic function that will handle the details of executing the Cypher queries from java, consume the result, and return it as an easy Map which maps the column name requested back to a list of results.

The trouble is that some of my ResourceIterator responses that come back from ExecutionResult appear empty, although they shouldn't be. I'm wondering if there is a need to consume multiple ResourceIterators in parallel, or some other hitch that's causing them to be exhausted before I've read them.

public Map<String,List<Object>> runQueryComplexResult(NeoProfiler parent, String query, String...columns) {
    HashMap<String,List<Object>> all = new HashMap<String,List<Object>>();

    ExecutionEngine engine = new ExecutionEngine(parent.getDB());
    List<Object> retvals = new ArrayList<Object>();

    try ( Transaction tx = parent.getDB().beginTx() ) {
        log.info(query);
        ExecutionResult result = engine.execute(query);

        List<ResourceIterator<Object>> rits = new ArrayList<ResourceIterator<Object>>();
        List<List<Object>> consumed = new ArrayList<List<Object>>();

        for(String col : columns) { 
            // rits.add(result.columnAs(col));

            all.put(col, IteratorUtil.asList(result.columnAs(col)));
        }   
    }

    return all;
}

I then call this function like this:

    Map<String,List<Object>> ret = runQueryComplexResult(parent,
            "match n-[r:" + type + "]->m return n as left, m as right limit 50", 
            "right", "left");

In this case, the column in the result labeled "right" will be read first. When it is, I get an empty list of results for the "left" column. If I switch order (and read the results from "left" first) then the reverse happens; the "right" list is empty.

役に立ちましたか?

解決

It appears that you can only iterate once through the rows in an ExecutionResult. The columnAs() method iterates through all the rows, but only returns the values from a single column. A second call to columnAs() will return no values because you are already at the end of the ExecutionResult.

You will need to restructure your logic and use the iterator() method instead, processing a row at a time.

To quote the JavaDoc for iterator():

public ResourceIterator<Map<String,Object>> iterator()

Returns an iterator over the return clause of the query. The format is a map that has as keys the names of the columns or their explicit names (set via 'as') and the value is the calculated value. Each iterator item is one row of the query result.

In other words, each pass through an iterator() loop provides a Map containing the columns for a result row. Each key in the Map is the name of a column, and the value for each key is that column's data.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top