Reputation: 154
I have the given schema
(t1:Tag)-[c:CONNECTED_TO]-(t2:Tag)
Each relationship of type :CONNECTED_TO has a property that is storing dates as a list.
{
"dates": [
"2019-11-27",
"2019-01-24",
"2017-06-27"
]
}
Now I want to find each relationship where one of the dates is between two dates.
MATCH ()-[c:CONNECTED_TO]-()
WHERE ANY (item IN c.dates WHERE date({year: 2019, month: 12}) > item >= date({year: 2019, month: 10}))
RETURN c
But in addition, I also want to count how many dates in the list-property are between those two dates. For the above example, it should return 1 because only one date on the list is between 2019-12-01 and 2019-10-01.
How can I do that?
Edit
I found the following solution for my problem:
MATCH ()-[c:CONNECTED_TO]-()
WITH [x IN range(0,size(c.dates)-1) WHERE date({year: 2019, month: 12}) > c.dates[x] >= date({year: 2019, month: 1})] AS index, id(c) AS id
RETURN id, size(index) AS Size
Sadly this solution is very slow. The date-list can be of size 10.000 or higher. If there is somebody with a faster solution I would be happy to know.
Upvotes: 0
Views: 48
Reputation: 66999
MATCH
is scanning ALL the nodes in your database to find the CONNECTED_TO
relationships. You should be qualifying the end nodes with the Tag
label to scan just the Tag
nodes.date
values just once.REDUCE
function instead of list comprehension (which generates new lists that your query will just drop) to count the dates within range.RANGE
function, which also generates a list.This query should be faster:
WITH date({year: 2019, month: 12}) AS a, date({year: 2019, month: 1}) AS b
MATCH (:Tag)-[c:CONNECTED_TO]-(:Tag)
RETURN ID(c) AS id, REDUCE(s=0, d IN c.dates | CASE WHEN a > d >= b THEN s + 1 ELSE s END) AS Size
Upvotes: 2