cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

C's driver for parsing query result

oraiches
Node Link

Hi,
I'm having an issue with using the driver for neo4j in C.
I have a query which returns a collection without keys, also called a list (or an array).
I'm trying to iterate over its fields in order to parse it to another output of my choice but that didn't work out.
This is the query:

MATCH (i:Inode)                                      
WHERE i.ino=2 AND i.fsid=1         
MATCH p = (i)-[:IN_DIR*]->(:Inode {ino: 0})
UNWIND nodes(p) as nlist
WITH collect(nlist.name) as pathNames
RETURN pathNames, size(pathNames) as listSize;

The result array i'm getting is array of strings (names without special chars).

By the looks of the API, I need to retrieve any field and then consuming it with basic knowledge of its type. This is my C code (after checking the transaction was successful):

// fetch collection as a list(an ordered list of elements containing the names of dirs in destination path)
neo4j_value_t value_list = neo4j_result_field(result, 0);

// fetch the list's length from the other returned field of the query specified for this functionality
neo4j_value_t value_list_len = neo4j_result_field(result, 1);
long long list_len_res = neo4j_int_value(value_list_len);
if(list_len_res == 0) {
	// list is empty -> no result found (though query returned with success)
	return -1;
}

// parse the value of the list as a list that has reachable elements
neo4j_value_t list = neo4j_list(&value_list, list_len_res);

char tmp_buf[100];
for(int i = 0; i < list_len_res; ++i) {
	neo4j_value_t elem = neo4j_list_get(list, i);
	TEST_ASSERT(!neo4j_is_null(elem));
	neo4j_tostring(elem, tmp_buf, sizeof(tmp_buf));
	...(do stuff with tmp_buf)
}

But when I print insides of tmp_buf I get that:

  1. first iteration shows the whole array.
  2. second iteration shows a number (not a string that was in the array).

Any answer would help, thanks!

2 REPLIES 2

Hi @oraiches,

General usage is to run the query and obtain a neo4j_result_stream_t *results. You can then iterate over those results using neo4j_result_t *result = neo4j_fetch_next(results);, each result being the equivalent of a row in the query result table.

You can then obtain fields (columns) from each result (row) using neo4j_value_t value = neo4j_result_field(result, index);.

You can obtain the underlying data from the value by using the appropriate methods for it's type, e.g. neo4j_tostring(value, ...) for strings, neo4j_list_get(value, ...) for lists, etc. These are all described in the documentation. If you need to determine the type programmatically, there are methods for this as well.

The main issue I see in the code you have provided is that you're creating a new list using neo4j_value_t list = neo4j_list(&value_list, list_len_res);. You don't need to create one - your result will already have returned one that you just need to index into. E.g.

neo4j_value_t value_list = neo4j_result_field(result, 0);

TEST_ASSERT(neo4j_instanceof(value_list, NEO4J_LIST));

unsigned int list_len = neo4j_list_length(value_list);
for(int i = 0; i < list_len; ++i) {
    neo4j_value_t elem = neo4j_list_get(list, i);

    TEST_ASSERT(!neo4j_is_null(elem));
    TEST_ASSERT(neo4j_instanceof(elem, NEO4J_STRING));

    neo4j_tostring(elem, tmp_buf, sizeof(tmp_buf));
    ...(do stuff with tmp_buf)
}

Note that there was no need to use the second result field (listSize) as you can obtain the size of the list using neo4j_list_length(...) on the list itself.

If that doesn't solve your issue, it would be great if you provided a full code snippet.

oraiches
Node Link

It worked like charm!! thank you for explanation!