gqlalchemy icon indicating copy to clipboard operation
gqlalchemy copied to clipboard

Getting Node object from Edge

Open antoniofilipovic opened this issue 4 years ago • 5 comments

When I am working with an Edge, there is a scenario where I want to find which Node is it, and I only have Memgraph node ID, and not the whole object. And I would want further to make a query with those Nodes I got from Edge property, but I can't as I can't make a query towards database with Memgraph ID of Node.

In other words, it would be good to return Node instead of Node-id in Memgraph when calling edge.start_node or edge.end_node

antoniofilipovic avatar Nov 02 '21 16:11 antoniofilipovic

So the reason for this kind of implementation is twofold. Since the memgraph as per bolt specification returns not nodes but nodes id when fetching edge the only way to tackle this issue is from the client-side. Not there can be two solutions:

  1. One would be to implicitly change every user's query to fetch nodes as well and to bind the nodes to edges, which would make another layer of query parsing from the client's side that would be very complicated (you would need to return all the nodes that could be found in edges). Or make it easier but slower for, for every fetched edge performer another query that would get nodes (if that didn't already happen) => This solution is needlessly complex

  2. Another solution would be to keep the graph structure constantly in memory, in other words whenever a user would fetch nodes, we keep them in memory and map them if possible to edges (that's how neo4j does it). The issue is an obvious inconsistency, sometimes you get id and sometimes you get node...

And that's the reason this implementation has not changed much from current, I think what you are looking for is great but that would be a feature for a higher level querying (OGM)

jbajic avatar Nov 03 '21 10:11 jbajic

What do you @antoniofilipovic think about this?

jbajic avatar Nov 04 '21 11:11 jbajic

Considering solution 1., that was basically my idea, to expand query so if the user writes: MATCH ()-[edge]->() RETURN edge; we could expand such query to return nodes as labels, and map them on edge.

And for the 2. solution, I agree. And it's better (in my opinion) to have it this way than the 2. solution.

But I am not sure why would be complicated about expanding the query in 1. solution?

antoniofilipovic avatar Nov 04 '21 17:11 antoniofilipovic

I would say that is difficult and can run needlessly slow things down for the user who doesn't expect that more data will be fetched, or doesn't need to. So in the example, you provided we have: MATCH ()-[edge]->() RETURN edge; and that would be expanded to MATCH (n)-[edge]->(m) RETURN edge, n, m; which is pretty trivial. Let's take a look into other examples:

MATCH ()-[:ofGenre]->(:Genre {name:"Action"}) RETURN movie.title ORDER BY movie.title LIMIT 10; You cannot guarantee that you will get all edges since there is a limit, or:

MATCH ()-[edge]->(:L1) WITH edge MATCH (n:L2)<-[edge]-(m:L3:l4) WITH edge MATCH ()-[edge]->(:L5) RETURN edge; you would have to add nodes and pass them across with WITH clause which would slow things down significantly. Or even worse if you decide to mangle with UNION clause...

That's my reasoning for not implementing this out of the box since it's fairly easy for the user to do it, but it's troublesome if we decide to do it on a level like this where you simply want to run any kind of queries. I think this makes more sense to do in OGM since it would be higher level querying. (I admit the example are clumsy and silly, but there are just to show the issues with the example)

jbajic avatar Nov 05 '21 10:11 jbajic

Okay, I really didn't have an idea how such a feature could complicate things easily a lot. It makes sense for the user to handle nodes in a query then due to the reasons you provided. Thanks for such a detailed answer.

antoniofilipovic avatar Nov 10 '21 15:11 antoniofilipovic