unclear how to read an identity from a value.
Opened this issue · 5 comments
I'd like to read the neo4j_value_t identity value to an uint64_t?
There is no function "neo4j_identity_value(neo4j_value_t value)" defined?
I am trying
neo4j_value_t vId = neo4j_node_identity(value);
_id = static_cast<uint64_t>(vId._vdata._int);
but this doesn't seem to work in all cases.
Why and how can I get the value?
Thank you!
Hi @JensWalther,
So the current API intentionally avoided methods to convert identities to and from integers. I'm ok with revisiting this decision. However, I would like to understand the use-case.
Hi @cleishm
Background
I am building an application which is abstracting neo4j as one potential database.
Therefore I have abstract base classes called "Node" and "Rels".
I have an Object Factory which is managed using ids. For the Neo4j I am using the internal id as reference.
Problem
When reading path objects (Match path = (a)-[r]-(b) return path limit 1000), I am calling
neo4j_path_get_relationship
then I am parsing relationship value just like for a Query (Match (s), (d) Where ID(s) = 2 And ID(d) = 3 Merge (s)-[r:traces]->(d) return r)
--> I am using the same code here.
--> but when callingneo4j_relationship_start_node_identity
I am trying to detect the id by reading
neo4j_value_t vId = neo4j_relationship_start_node_identity(value);
Handle id = static_cast<Handle>(vId._vdata._int);
--> which always returns the value 0 in this case (while it works for returned relationships)
I should first mention that you shouldn't be accessing _vdata
, i.e. in static_cast<Handle>(vId._vdata._int)
. Those struct fields are undocumented and may not contain the data you're after.
I'll look at adding some functions to retrieve the uint64_t for the node id. However, it might be helpful for a reproducible test case that shows this returned 0
value.
#include
#include <neo4j-client.h>
bool test_readPathRelationship()
{
bool retVal = false;
std::ostringstream oss;
oss << "bolt://" << "neo4j" << ":" << "passwd" << "@" << "10.0.2.2" << ":" << "7687";
neo4j_connection_t* _pSession = neo4j_connect(oss.str().c_str(),
NULL,
NEO4J_INSECURE);
std::ostringstream streamNodeQ;
streamNodeQ << "Match path = (a)-[r]->(b) return path limit 1000";
std::cout << "Execute getAllPaths Query: '" << streamNodeQ.str() << "'" << std::endl;
std::string statement = streamNodeQ.str();
neo4j_result_stream_t * results = neo4j_run(_pSession, statement.c_str(), neo4j_null);
unsigned int ncolumns = 0;
if ((results == NULL) || (ncolumns=neo4j_nfields(results)) == 0)
{
neo4j_perror(stderr, errno, "Failed to retrieve results");
retVal = true;
}
else
{
neo4j_result_t* result = NULL;
while ((result = neo4j_fetch_next(results)) != NULL)
{
neo4j_value_t value = neo4j_result_field(result, 0);
if (neo4j_instanceof(value, NEO4J_PATH) )
{
uint64_t _length = neo4j_path_length(value);
if (!_length )
{
std::cout << "Path has no length" << std::endl;
retVal = EXIT_FAILURE;
}
for (size_type i=0;i<_length;i++)
{
uint64_t id = UINT64_MAX;
bool bNaturallyTraversedForward = 0;
neo4j_value_t relsValue = neo4j_path_get_relationship(value, i, &bNaturallyTraversedForward);
if (neo4j_instanceof(relsValue, NEO4J_RELATIONSHIP) == true)
{
neo4j_value_t vId = neo4j_relationship_identity(relsValue);
id = static_cast<uint64_t>(vId._vdata._int); // ok
if ( id == UINT64_MAX)
{
std::cout << "relationship id not retrieved" << std::endl;
retVal = true;
break;
}
neo4j_value_t vIdStart = neo4j_relationship_start_node_identity(relsValue);
uint64_t idStartNode = static_cast<uint64_t>(vIdStart._vdata._int); // always 0
std::cout << "startNodeId" << idStartNode << std::endl;
}
}
} // if
} // while
} // else
return retVal;
}
I hope I removed all my "own" types
The problem of reading the start node identity occurs, in the cascade of reading
- a path length
- a path relationship
- and the start node identifier of that relationship