在 ArangoDB 中过滤两个 child 属性的简洁方法(AQL / Spring Data ArangoDB)
Concise way to filter on two child attributes in ArangoDB (AQL / Spring Data ArangoDB)
在 ArangoDB 中,我在 trip
collection 中有文档,它通过 tripToDriver
[=] 中的边与 driver
collection 中的文档相关30=],旅行文档也通过 departureToTrip
collection.
中的边与 departure
collection 中的文档相关
要获取他们的 driver 具有给定 idNumber 且其关联的出发时间在提供的 date/time 之后有开始时间的行程,我已经成功编写了以下 AQL:
FOR doc IN trip
LET drivers = (FOR v IN 1..1 OUTBOUND doc tripToDriver RETURN v)
LET departures = (FOR v in 1..1 INBOUND doc departureToTrip RETURN v
FILTER drivers[0].idNumber == '999999-9999' AND departures[0].startTime >= '2018-07-30'
RETURN doc
但我想知道是否有更简洁/优雅的方式来达到同样的效果?
一个相关的问题,因为我使用的是 Spring Data ArangoDB:是否有可能通过派生查询获得此结果?
对于单个关系,我能够创建如下查询:
Iterable<Trip> findTripsByDriversIdNumber( String driverId );
但没有运气将出发关系纳入此签名(可能是因为它是入站的?)。
首先,只有当您每次旅行只有一个连接 driver/departure 时,您的查询才有效。您正在获取所有链接的驱动程序,但只检查第一个找到的驱动程序。
如果这是你的模型,那完全没问题,但我建议在子查询中进行 idNumber
/startTime
检查。然后,因为我们只需要知道至少有一个driver/departure符合我们的过滤条件,所以我们在子查询中加一个LIMIT 1
而return只加一个true
。这足以满足我们在主查询中 FITLER
的需要。
FOR doc IN trip
FILTER (FOR v IN 1..1 OUTBOUND doc tripToDriver FILTER v.idNumber == @idNumber LIMIT 1 RETURN true)[0]
FILTER (FOR v IN 1..1 INBOUND doc departureToTrip FILTER v.startTime >= @startTime LIMIT 1 RETURN true)[0]
RETURN doc
我测试过使用派生查询来解决您的问题。如果当前的 arangodb-spring-data 版本中没有错误,它会起作用。该错误已修复但尚未发布。您已经可以使用 arangodb-spring-data
的快照版本对其进行测试(1.3.1-SNAPSHOT
或 2.3.1-SNAPSHOT
,具体取决于您的 Spring 数据版本,请参阅 supported versions)。
以下派生查询方法适用于快照版本。
Iterable<Trip> findByDriversIdNumberAndDeparturesStartTimeGreaterThanEqual(String idNumber, LocalDate startTime);
要使派生查询正常工作,您需要在 class Trip
中添加以下带注释的字段
@Relations(edges = TripToDriver.class, direction = Direction.OUTBOUND, maxDepth = 1)
private Collection<Driver> drivers;
@Relations(edges = DepartureToTrip.class, direction = Direction.INBOUND, maxDepth = 1)
private Collection<Departure> departures;
我还创建了一个工作 example project on github。
在 ArangoDB 中,我在 trip
collection 中有文档,它通过 tripToDriver
[=] 中的边与 driver
collection 中的文档相关30=],旅行文档也通过 departureToTrip
collection.
departure
collection 中的文档相关
要获取他们的 driver 具有给定 idNumber 且其关联的出发时间在提供的 date/time 之后有开始时间的行程,我已经成功编写了以下 AQL:
FOR doc IN trip
LET drivers = (FOR v IN 1..1 OUTBOUND doc tripToDriver RETURN v)
LET departures = (FOR v in 1..1 INBOUND doc departureToTrip RETURN v
FILTER drivers[0].idNumber == '999999-9999' AND departures[0].startTime >= '2018-07-30'
RETURN doc
但我想知道是否有更简洁/优雅的方式来达到同样的效果?
一个相关的问题,因为我使用的是 Spring Data ArangoDB:是否有可能通过派生查询获得此结果?
对于单个关系,我能够创建如下查询:
Iterable<Trip> findTripsByDriversIdNumber( String driverId );
但没有运气将出发关系纳入此签名(可能是因为它是入站的?)。
首先,只有当您每次旅行只有一个连接 driver/departure 时,您的查询才有效。您正在获取所有链接的驱动程序,但只检查第一个找到的驱动程序。
如果这是你的模型,那完全没问题,但我建议在子查询中进行 idNumber
/startTime
检查。然后,因为我们只需要知道至少有一个driver/departure符合我们的过滤条件,所以我们在子查询中加一个LIMIT 1
而return只加一个true
。这足以满足我们在主查询中 FITLER
的需要。
FOR doc IN trip
FILTER (FOR v IN 1..1 OUTBOUND doc tripToDriver FILTER v.idNumber == @idNumber LIMIT 1 RETURN true)[0]
FILTER (FOR v IN 1..1 INBOUND doc departureToTrip FILTER v.startTime >= @startTime LIMIT 1 RETURN true)[0]
RETURN doc
我测试过使用派生查询来解决您的问题。如果当前的 arangodb-spring-data 版本中没有错误,它会起作用。该错误已修复但尚未发布。您已经可以使用 arangodb-spring-data
的快照版本对其进行测试(1.3.1-SNAPSHOT
或 2.3.1-SNAPSHOT
,具体取决于您的 Spring 数据版本,请参阅 supported versions)。
以下派生查询方法适用于快照版本。
Iterable<Trip> findByDriversIdNumberAndDeparturesStartTimeGreaterThanEqual(String idNumber, LocalDate startTime);
要使派生查询正常工作,您需要在 class Trip
@Relations(edges = TripToDriver.class, direction = Direction.OUTBOUND, maxDepth = 1)
private Collection<Driver> drivers;
@Relations(edges = DepartureToTrip.class, direction = Direction.INBOUND, maxDepth = 1)
private Collection<Departure> departures;
我还创建了一个工作 example project on github。