Neo4j仅当where子句始终为true时才返回节点

时间:2022-04-08 18:04:15

Consider the following Neo4j Database example:

考虑以下Neo4j数据库示例:

Nodes are (Basket) (Booking) and [:IS_BOOKED_IN]

节点是(篮子)(预订)和[:IS_BOOKED_IN]

Now Booking looks like this: Booking {start: number, end: number}

现在预订如下:预订{start:number,end:number}

If you book something you choose which basket you want to book it with and the relationship [:IS_BOOKED_IN] gets created between those two.

如果您预订了某些内容,您可以选择要预订的篮子,并在这两者之间创建关系[:IS_BOOKED_IN]。

This works perfectly fine.

这完全没问题。

Now I want to check on my next booking if ANY basket is available for the timeframe that I select.

现在我想检查下一次预订,如果我选择的时间范围内有任何篮子可用。

Right now I'm doing this in Cypher with this query:

现在我正在使用此查询在Cypher中执行此操作:

MATCH (basket:Basket)-[:IS_BOOKED_IN]->(booking:Booking) WHERE ({start} < booking.start AND {end} < booking.start) OR ({end} > booking.end AND {start} > booking.end) RETURN basket

MATCH(篮:篮) - [:IS_BOOKED_IN] - >(预订:预订)WHERE({开始} booking.end AND {开始}> booking.end)返回篮子

{start} and {end} are numbers

{start}和{end}是数字

As you can see this will work as expected, but only if there is just one booking. As soon as there are more bookings I will get the same basket back, even though it is obviously not available, thus making my query useless.

正如您所看到的,这将按预期工作,但仅限于只有一个预订。一旦有更多的预订,我会得到相同的篮子,即使它显然不可用,因此使我的查询无用。

This happens because the query doesn't stop when the WHERE clause fails, instead it takes the same Basket node again and checks the other bookings, which don't fail and in turn give me back the basket..

发生这种情况是因为WHERE子句失败时查询没有停止,而是再次使用相同的Basket节点并检查其他预订,这些预订不会失败,反过来又会让我回到篮子里。

How can I change this, how can I tell Neo4j to only return the basket to me if the WHERE clause is always true? Or just skip the basket if it fails just once..

如何改变这一点,如果WHERE子句始终为真,我怎么能告诉Neo4j只将篮子归还给我?或者只是跳过篮子,如果它只失一次..

Any ideas appreciated, thank you

感谢任何想法,谢谢

2 个解决方案

#1


2  

You can use a collection, i.e. collect and then the ALL predicate.

您可以使用集合,即收集,然后使用ALL谓词。

MATCH (basket:Basket)-[:IS_BOOKED_IN]->(booking:Booking) 
WITH basket, collect(booking) as bookings
WHERE ALL(booking in bookings WHERE
       ({start} < booking.start AND {end} < booking.start) 
    OR ({end} > booking.end AND {start} > booking.end))
RETURN basket

#2


0  

I think you are looking for CASE expression see Neo4j documentation

我想您正在寻找CASE表达式,请参阅Neo4j文档

Case can be used to return the result only if it meets your requirements.

Case只有在满足您的要求时才能用于返回结果。

Example:

MATCH (u:User) WHERE u.name = "foo"
RETURN CASE when u.age > 18 THEN u ELSE null END as result

Another solution can be to change "OR" for "AND" in your WHERE clause, then the result will be taken only if the two conditions are met.

另一个解决方案是在WHERE子句中为“AND”更改“OR”,然后仅在满足两个条件时才会获得结果。

#1


2  

You can use a collection, i.e. collect and then the ALL predicate.

您可以使用集合,即收集,然后使用ALL谓词。

MATCH (basket:Basket)-[:IS_BOOKED_IN]->(booking:Booking) 
WITH basket, collect(booking) as bookings
WHERE ALL(booking in bookings WHERE
       ({start} < booking.start AND {end} < booking.start) 
    OR ({end} > booking.end AND {start} > booking.end))
RETURN basket

#2


0  

I think you are looking for CASE expression see Neo4j documentation

我想您正在寻找CASE表达式,请参阅Neo4j文档

Case can be used to return the result only if it meets your requirements.

Case只有在满足您的要求时才能用于返回结果。

Example:

MATCH (u:User) WHERE u.name = "foo"
RETURN CASE when u.age > 18 THEN u ELSE null END as result

Another solution can be to change "OR" for "AND" in your WHERE clause, then the result will be taken only if the two conditions are met.

另一个解决方案是在WHERE子句中为“AND”更改“OR”,然后仅在满足两个条件时才会获得结果。