memgraph / gqlalchemy

GQLAlchemy is a library developed with the purpose of assisting in writing and running queries on Memgraph. GQLAlchemy supports high-level connection to Memgraph as well as modular query builder.
https://pypi.org/project/gqlalchemy/
Apache License 2.0
227 stars 32 forks source link

Getting Node object from Edge #30

Open antoniofilipovic opened 3 years ago

antoniofilipovic commented 3 years ago

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

jbajic commented 3 years ago

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 commented 3 years ago

What do you @antoniofilipovic think about this?

antoniofilipovic commented 3 years ago

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?

jbajic commented 3 years ago

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)

antoniofilipovic commented 3 years ago

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.