How to properly use MATCH inside UNWIND for a Nebula query - graph

I’m currently working with the Nebula graph database for the first time and I’m running into some issues with a query. In terms of the schema, I have “Person” nodes, which have a “name” property, as well as Location nodes also with a name property. These node types can be connected by a relationship edge, called HAS_LIVED (to signify whether a person has lived in a certain location). Now for the query, I have a list of names (strings). The query looks like:
UNWIND [“Anna”, “Emma”, “Zach”] AS n
MATCH (p:Person {name: n})-[:HAS_LIVED]->(loc)
RETURN loc.Location.name
This should return a list of three places, i.e. [“London”, “Paris”, “Berlin”]. However, I am getting nothing as a result from the query. When I get rid of the UNWIND and write three separate MATCH queries with each name, it works individually. Not sure why.

Try this instead. It is using "where" clause.
UNWIND [“Anna”, “Emma”, “Zach”] AS n
MATCH (p:Person)-[:HAS_LIVED]->(loc)
where p.name = n
RETURN loc.Location.name

Related

Why can't I MATCH (v:<tag>)-[e:<edge>]-(v2:<tag>) RETURN v LIMIT 10 in the NebulaGraph database

The Nebula Graph docs say that "When traversing all vertices of the specified Tag or edge of the specified Edge Type, such as MATCH (v:player) RETURN v LIMIT N, there is no need to create an index, but you need to use LIMIT to limit the number of output results." But when I run the statement in the preceding screenshot, it told me that I did not have a limit number, which I did.
What is the correct way to RETURN v without creating indexes?
I met the same issue before. Actually, when you specify both a tag and an edge for a query simultaneously, you need to create an index for the tag or the edge first.
Create an index for the tag company first and then try to execute it again.

Gremlin code to find 1 vertex with specific property

I want to return a node where the node has a property as a specific uuid and I just want to return one of them (there could be several matches).
g.V().where('application_uuid', eq(application_uuid).next()
Would the above query return all the nodes? How do I just return 1?
I also want to get the property map of this node. How would I do this?
You would just do:
g.V().has('application_uuid', application_uuid).next()
but even better would be the signature that includes the vertex label (if you can):
g.V().has('vlabel', 'application_uuid', application_uuid).next()
Perhaps going a bit further if you explicitly need just one you could:
g.V().has('vlabel', 'application_uuid', application_uuid).limit(1).next()
so that both the graph provider and/or Gremlin Server know your intent is to only next() back one result. In that way, you may save some extra network traffic/processing.
This is a very basic query. You should read more about gremlin. I can suggest Practical Gremlin book.
As for your query, you can use has to filter by property, and limit to get specific number of results:
g.V().has('application_uuid', application_uuid).limit(1).next()
Running your query without the limit will also return a single result since the query result is an iterator. Using toList() will return all results in an array.

Neo4j - how to include start node in my query?

I'm attempting to build a recommendation engine for a library system.
This is my db schema:
My starting point is a LoanerCard. The flow is then supposed to look like this: Get all copies -> get the material -> get all copies of the material (including the original) -> get LoanerCard from copy -> get all loaned copies -> return the material name of the copies + an aggregated count to indicate the strength of the recommendation.
My best attempt so far has resulted in this query:
MATCH (L:LoanerCard {Barcode:"10007"})-[:LOANED]->(myLoans)-[:COPY_OF]-
(masterMaterial),
(masterMaterial)<-[:COPY_OF]-(allCopies),
(allCopies)<-[:LOANED]-(coLoaners),
(coLoaners)-[r:LOANED]->(theirCopies),
(theirCopies)-[:COPY_OF]-(materials)
RETURN materials.Title as Recommended, count(*) as Strength ORDER BY Strength DESC
My issue here is that when I traverse the graph it doesn't include the original copy and the adjacent LoanerCards of that so essentially it only traverses the area circled in red and never reaches LoanerCard 10817 and 10558
How can I design my query so it includes these?
A MATCH clause automatically filters out duplicate relationships. Therefore, in order to traverse the same relationships twice, you need to split your MATCH clause in two.
Try this:
MATCH (:LoanerCard {Barcode:"10007"})-[:LOANED]->()-[:COPY_OF]-(masterMaterial)
MATCH (masterMaterial)<-[:COPY_OF]-()<-[:LOANED]-()-[:LOANED]->()-[:COPY_OF]-(materials)
RETURN materials.Title as Recommended, count(*) as Strength ORDER BY Strength DESC

Neo4j Cypher: Return a list of distinct edge types with number of occurences

I know I can return all distinct edge types like so:
MATCH (a)-[r]->(b)
RETURN distinct(type(r))
How can I return each distinct type along with the number of occurrences?
If you know the type, you can make a query using the counts store which is instant.
MATCH ()-[r:ACTED_IN]->()
RETURN count(r) as count
Unfortunately relationship types aren't dynamic in Cypher, you can't specify them via parameters or string values (as a result of your previous query, for example).
If you have APOC Procedures, there's a procedure that will quickly get you exactly what you want, however, a piece of data from the apoc.meta.stats() call.
CALL apoc.meta.stats() YIELD relTypesCount
RETURN relTypesCount
match ()-[r]->() return type(r),count(*)

Get path lengths for every relationship neo4j

So I have a graph that looks like this(starting from the rightmost side) with relationships that have a unique number attribute called Isnad. I want to write a query to get the length of every Isnad from the start node to the end node but I can't figure it out. I don't know how to traverse every path for every Isnad separately. Any help?
I don't know if it is the most elegant and solution, but I think it works. First, I'm getting all unique Isnad values of relationships outgoing from the rightmost side node using an identifier. Then I'm using a variable-length pattern matching where all relationships have the same value for Isnad property. Then the Isnad value and the path length are returned.
match ({id:'unique-identifier-of-rightmost-side-node'})-[r]->()
with distinct r.Isnad as Isnad
match p = ()-[*{Isnad : Isnad}]->()
return Isnad, length(p) as Length

Resources