I have a query that I am trying to execute. The query works, but there isn't an option to see this data in graph format. Instead the data is returned in table/text format.
When I simplify the query, the output is displayed in graph format - No idea why,
This is the query that is giving me the issue:
MATCH (p:Person)-[hi:hasIdentity]->(i:Identity)
MATCH (j:Person)-[hi2:hasIdentity]->(i2:Identity)
MATCH (i)-[bl:Linked]->(i2)
WHERE NOT p=j
return DISTINCT(p.id), COUNT(DISTINCT(j))
LIMIT 5
Does anyone have any idea why that might be the case?
You'll need to return variables associated with nodes and/or relationships for it to display as a graph. As it is now you're returning properties of nodes (p.id), probably integers or strings. Try this return instead:
...
RETURN p, COUNT(DISTINCT j)
LIMIT 5
By the way, DISTINCT isn't a function, no need for parenthesis, and when you have a RETURN or WITH that has an aggregation, you don't need to use DISTINCT for that line since the non-aggregation variables become distinct since they act as the grouping key for the aggregation.
Related
How does the where condition in neo4j works ?
I have simple data set with following relationship =>
Client -[CONTAINS {created:"yesterday or today"}]-> Transaction -[INCLUDES]-> Item
I would like to filter above to get the items for a transaction which were created yesterday, and I use the following query -
Match
(c:Client) -[r:CONTAINS]-> (t:Transaction),
(t) -[:INCLUDES]-> (i:Item)
where r.created="yesterday"
return c,t,i
But it still returns the dataset without filtering. What is wrong ? And how does the filtering works in neo4j for multiple MATCH statements say when I want to run my query on filetered dataset from previous steps?
Thank you very much in advance.
Your query seems fine to me. However, there are 2 things I would like to point out here:
In this case, the WHERE clause can be removed and use match by property instead.
The MATCH clause can be combined.
So, the query would be:
MATCH (c:Client) -[r:CONTAINS {created: "yesterday"}]-> (t:Transaction) -[:INCLUDES]-> (i:Item)
RETURN c, t, i
Regarding your second question, when you want to run another query on the filtered dataset from the previous step, use WITH command. Instead of returning the result, WITH will pipe your result to the next query.
For example, with your query, we can do something like this to order the result by client name and return only the client:
MATCH (c:Client) -[r:CONTAINS {created: "yesterday"}]-> (t:Transaction) -[:INCLUDES]-> (i:Item)
WITH c, t, i
ODERBY c.name DESC
RETURN c
There does not seem to be anything wrong with the cypher statement.
Applying subsequent MATCH statements can be done with the WITH clause, it's well documented here : https://neo4j.com/docs/cypher-manual/current/clauses/with/
match(m:master_node:Application)-[r]-(k:master_node:Server)-[r1]-(n:master_node)
where (m.name contains '' and (n:master_node:DeploymentUnit or n:master_node:Schema))
return distinct m.name,n.name
Hi,I am trying to get total number of records for the above query.How I change the query using count function to get the record count directly.
Thanks in advance
The following query uses the aggregating funtion COUNT. Distinct pairs of m.name, n.name values are used as the "grouping keys".
MATCH (m:master_node:Application)--(:master_node:Server)--(n:master_node)
WHERE EXISTS(m.name) AND (n:DeploymentUnit OR n:Schema)
RETURN m.name, n.name, COUNT(*) AS cnt
I assume that m.name contains '' in your query was an attempt to test for the existence of m.name. This query uses the EXISTS() function to test that more efficiently.
[UPDATE]
To determine the number of distinct n and m pairs in the DB (instead of the number of times each pair appears in the DB):
MATCH (m:master_node:Application)--(:master_node:Server)--(n:master_node)
WHERE EXISTS(m.name) AND (n:DeploymentUnit OR n:Schema)
WITH DISTINCT m.name AS n1, n.name AS n2
RETURN COUNT(*) AS cnt
Some things to consider for speeding up the query even further:
Remove unnecessary label tests from the MATCH pattern. For example, can we omit the master_node label test from any nodes? In fact, can we omit all label testing for any nodes without affecting the validity of the result? (You will likely need a label on at least one node, though, to avoid scanning all nodes when kicking off the query.)
Can you add a direction to each relationship (to avoid having to traverse relationships in both directions)?
Specify the relationship types in the MATCH pattern. This will filter out unwanted paths earlier. Once you do so, you may also be able to remove some node labels from the pattern as long as you can still get the same result.
Use the PROFILE clause to evaluate the number of DB hits needed by different Cypher queries.
You can find examples of how to use count in the Neo4j docs here
In your case the first example where:
count(*)
Is used to return a count of each returned item should work.
I have multiple nodes and relationships in neo4j, certain nodes have relationship depth as 4, while certain have 2. I'm using neo4j's HTTP API to get the data in graph format
Sample query:
MATCH p= (n:datasource{resource_key:'ABCD'})-[:is_dataset_of]-(c:dataset)-[q]-(v:dataset_columns)-[s]-(b:component)-[w]-(e:dashboard) return p
If i use this query then i can get output if this exact relationship is present but I also want to get the output if the 2nd relationship is not available, Any pointers on how to achieve this?
Here is one way:
MATCH p = (:person1 {hobby: 'gamer'})-[:knows]-(:person2)
RETURN p
UNION ALL
MATCH p = (:person1 {hobby: 'gamer'})-[:knows]-(:person2)--(:person3)
RETURN p
The UNION clause combines the results of 2 queries. And the ALL option tells UNION to not bother to remove duplicate results (since the 2 subqueries will never produce the same paths).
If you really want the path to be returned, you can do something along these lines, using apoc (https://neo4j-contrib.github.io/neo4j-apoc-procedures/3.4/nodes-relationships/path-functions/)
MATCH requiredPath=(n)-[r]->(m)
OPTIONAL MATCH optionalPath = (m)-[q]->(s)
RETURN apoc.path.combine(requiredPath,optionalPath) AS p
I am new to Neo4J and struggling to get the output I need without extra external processing. I am pretty sure that Neo4J is easily capable of doing that. Please advice on best approach.
I have a 2 types of nodes: Ingredient and Function that are connected using relation that has property of {Weight: 1}. I am querying a list of ingredients and I want to get a sum of connections multiplied by weight of each connection leading to each distinct function.
Here's what I came up with.
MATCH (q:Ingredient)-[r]->(p) WHERE q.RefNo IN [1,2,3] RETURN r,p
This produces following output
{"weight":1}│{"Function":"X1"}
{"weight":0.5}│{"Function":"X1"}
{"weight":0.7}│{"Function":"X2"}
{"weight":0.4}│{"Function":"X3"}
{"weight":0.5}│{"Function":"X4"}
What I want to get in a single/stacked query is
X1:1.5, X2:1=0.7, X3:0.4, X4:0.5
Please advice on possible solution of this problem.
Almost there, you just need to use an aggregation function (in this case, sum()) on the weight, and the Function property as your non-aggregation column:
MATCH (q:Ingredient)-[r]->(p)
WHERE q.RefNo IN [1,2,3]
RETURN p.Function, sum(r.weight) as weight
Or if you only want a single row result:
MATCH (q:Ingredient)-[r]->(p)
WHERE q.RefNo IN [1,2,3]
WITH p, sum(r.weight) as weight
RETURN collect(p {.Function, weight}) as functionWeights
I am trying to search for a key word on all the indexes. I have in my graph database.
Below is the query:
start n=node:Users(Name="Hello"),
m=node:Location(LocationName="Hello")
return n,m
I am getting the nodes and if keyword "Hello" is present in both the indexes (Users and Location), and I do not get any results if keyword Hello is not present in any one of index.
Could you please let me know how to modify this cypher query so that I get results if "Hello" is present in any of the index keys (Name or LocationName).
In 2.0 you can use UNION and have two separate queries like so:
start n=node:Users(Name="Hello")
return n
UNION
start n=node:Location(LocationName="Hello")
return n;
The problem with the way you have the query written is the way it calculates a cartesian product of pairs between n and m, so if n or m aren't found, no results are found. If one n is found, and two ms are found, then you get 2 results (with a repeating n). Similar to how the FROM clause works in SQL. If you have an empty table called empty, and you do select * from x, empty; then you'll get 0 results, unless you do an outer join of some sort.
Unfortunately, it's somewhat difficult to do this in 1.9. I've tried many iterations of things like WITH collect(n) as n, etc., but it boils down to the cartesian product thing at some point, no matter what.