Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Driver not exposing id property #180

Closed
aryzing opened this issue Dec 26, 2016 · 5 comments
Closed

Driver not exposing id property #180

aryzing opened this issue Dec 26, 2016 · 5 comments

Comments

@aryzing
Copy link

aryzing commented Dec 26, 2016

When using the neo4j browser (the builtin browser at localhost:7474) I can see that the ID of a node (correct me if I'm wrong) appears twice in the JSON, once as an object with using the low/high notation, and the other as the id property with the id as a string:

screenshot from 2016-12-27 00-45-31

However, when using the driver and attempting to access the id property, it evaluates to undefined. Actually, console.log-ing a record reveals that the id property isn't seen by the driver:

Record {
  keys: [ 'subject', 'id' ],
  length: 2,
  _fields: 
   [ Node { identity: [Object], labels: [Object], properties: [Object] },
     Integer { low: 9, high: 0 } ],
  _fieldLookup: { subject: 0, id: 1 } }

I'd really like to use the stringified id prop made available in the JSON returned by the neo4j server. Is this a bug or am I using it wrong?

Thanks

@lutovich
Copy link
Contributor

Hi @aryzing,

Could you please share queries you use?
Usually it should be possible to explicitly ask for id in the cypher query like this
MATCH (n) return id(n) AS nodeId, n AS node
and then extract it from the record record.get('nodeId').

@aryzing
Copy link
Author

aryzing commented Dec 27, 2016

Hi @lutovich , thanks for the quick response.

The screenshot came from

MATCH (u:User)-[:KNOWS]->(subject) WHERE u.username = 'test' RETURN subject

and the (partial) console.loged output came from

MATCH (u:User)-[:KNOWS]->(s) WHERE u.username = 'test' RETURN s, ID(s) AS id`

In the logged output, the record has a second field (an object with low/high props) representing the ID, but I don't really know what to do with it to get the ID as a string, which is why I was hoping to get it from the id prop of the first field (a Node) as seen in the localhost browser output. However, when using the driver, the id prop does not appear as part of the node's properties.

Using the second query, the output for record.get('s') and record.get('id') are

# record.get('s')
Node {
  identity: Integer { low: 10, high: 0 },
  labels: [ 'AUK' ],
  properties: { file: 'chemistry_notes.md', name: 'chemistry' } }
  #  <--- where is the node's `id` prop?

# record.get('id')
Integer { low: 10, high: 0 } # how do i get the id from this object?.

I now understand that to transform an Integer into its string representation I can simply use its .toString() method.

However, I'm still curious as to why a node's id prop does not appear when using the JavaScript driver as seen in the localhost:7474 browser output?

Thanks!

@lutovich
Copy link
Contributor

@aryzing there is a problem with number representation in JS driver: https://github.com/neo4j/neo4j-javascript-driver#a-note-on-numbers-and-the-integer-type. As you've already mentioned it should be enough to do record.get('id').toString() to get id as string.

Generally it is not a good idea to rely on node ids. Node/relationship id is basically an internal thing (offset of record on disk) that got exposed as is. They are not guaranteed to be stable and will probably change shape in future. Please create your own indexed property, if you can.

Id is part of record fields for queries that say ...RETURN id(n)... explicitly:

Record {
  keys: [ 'nodeId', 'n' ],
  length: 2,
  _fields:
   [ Integer { low: 9384298, high: 0 },
     Node { identity: [Object], labels: [], properties: {} } ],
  _fieldLookup: { nodeId: 0, n: 1 } }

but it is not included in nodes that are part of such records. This is so because ids will most likely change in future so we did not want to expose current numeric format.
I think browser always needs node/relationship ids to display them in visualization, maybe this is the reason why ids are always in REST api.

@aryzing
Copy link
Author

aryzing commented Dec 27, 2016

Awesome, thanks for clarifying!

@aryzing aryzing closed this as completed Dec 27, 2016
@jacob-ebey
Copy link

jacob-ebey commented Jul 13, 2018

//Rehashing for a teachable moment

For anyone interested in a simple implementation for the browser that gets around the 32 bit limitation of bit-wise operators or just came to understand what the "high" "low" represents:

function toNumber({ low, high }) {
  let res = high

  for (let i = 0; i < 32; i++) {
    res *= 2
  }

  return low + res
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants