Open antoniofilipovic opened 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:
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
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)
What do you @antoniofilipovic think about this?
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?
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)
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.
When I am working with an
Edge
, there is a scenario where I want to find whichNode
is it, and I only haveMemgraph node ID
, and not the whole object. And I would want further to make a query with thoseNodes
I got fromEdge
property, but I can't as I can't make a query towards database withMemgraph ID of Node
.In other words, it would be good to return
Node
instead ofNode-id in Memgraph
when callingedge.start_node
oredge.end_node