问题
Suppose that i have a graph in which for each pair of nodes m,n of type BallT there can be a node k of type BallD that connects them through relationships of type Rel, that is, there can be multiple patterns of the kind p=(m:BallT)-[r:Rel]-(k:BallD)-[s:Rel]-(n:BallT)
. For a given node m
(satisfying for example m.key="whatever"
) let's call Nmn the number of BallD connecting m and some node n and N the total number of BallD nodes. For this given node m how can i found all nodes n such that Nmn > N/2 and order the results by Nnm? I'm trying the query:
match (D:BallD)
with count(D) as N
match (m:BallT {key:"whatever"})-[r]-(d:BallD)-[s]-(n:BallT)
with N, distinct n as n_dist, count(d) as Nmn
where Nmn >= N
return n_dist
order by Nmn
but i'm getting
Invalid input 't': expected whitespace, comment, node labels, MapLiteral, a parameter, a relationship pattern
回答1:
Does this query do what you want?
MATCH (D:BallD)
WITH count(D) as N
MATCH (m:BallT {key:"whatever"})--(d:BallD)--(n:BallT)
WITH N, n, count(d) as Nmn
WHERE Nmn >= N/2
RETURN n, Nmn
ORDER BY Nmn
When using an aggregation function (like
count
) over a value (liken
), you do not need to useDISTINCT
to qualify the value that you are aggregating over -- that is done automatically for you.The
ORDER BY
argument must refer to a part of the returned values.Also, I corrected the
WHERE
clause to useN/2
.
回答2:
Just for future reference!! What i was trying to do: I have an array of keys ["k1",..,"kn"] that occur in a map d. For each key ki (i=1,..,n) i want to create nodes for it (if not already created), count the number of occurrences of ki in that map as well as to increment the total number of occurrences of ki in all maps that i eventually going to insert in database. To perform this bunch of create i perform this query:
create (d:Map)
with d
unwind [k1,...,kn] as k0
with distinct k0 as kd0, count(k0) as c, d
merge (k:Key {key: kd0})
on create set t.count = c, t.mapCount = 1
on match set t.count = t.count + c, t.mapCount = t.mapCount + 1
create (d)-[r:Contains {count: c}]->(t)
return t
Note that in this query i register the total number of occurrences of ki in the node that represents it and the number of occurrences of it in some map d in the relationship (of type Contains) that relates both (sorry my bad english! hehe)
Afterwards, lets say i want to find all keys k that co-occur with keys [k1,...,kn] (i.e., through some map d) but restricted to those keys k that co-occur "a lot" with ki (i.e., the number of maps that relates k and ki with i=1,..,n is bigger than M), but do not occur "a lot" in general (i.e., the number of maps that k occur in general is less than N). In this case i perform the following query:
unwind [k1,...,kn] as ki
match (:Key {key: ki})<-[r:Contains]-(d:Map)-[s:Contains]->(k:Key)
where k.mapCount < N
with distinct(k) as kd, count(d) as x
where x > M
return kd
order by x desc, kd.count desc
limit 5
Note that in this query i order the results first by x (the number of maps that contains both ki and k) and second by the number of occurrences of k, i.e., if two k's has the same x, then put first the k's with higher count.
Thanks a lot for the replies guys.... i have never been a frequent user of StackOverflow, but now i think i gonna use it a lot!! :)
来源:https://stackoverflow.com/questions/29100010/complex-query-with-agregation-in-where-clause