如何从 N1QL 查询中的嵌套数组中提取最大值和最小值?
How do you extract the maximum and minimum value from a nested array in N1QL query?
背景
我正在运行进行以下查询(我知道它可能难以阅读,所以我会在之后澄清它在做什么):
SELECT *
FROM `my_bucket` AS a
NEST (
SELECT c.toNode, c.fromNode, d.endDateTime, d.startDateTime
FROM `my_bucket` AS c
JOIN (
SELECT id, customAttributes.endDateTime, customAttributes.startDateTime
FROM `my_bucket`
WHERE type='airNode'
AND customAttributes.endDateTime >= CLOCK_UTC()
AND customAttributes.endDateTime <= DATE_ADD_STR(CLOCK_UTC(), 14, 'day')) AS d ON c.toNode = d.id
AND c.type='relNode') b ON a.id = b.fromNode AND a.type='edNode';
本质上,这里发生的是我们从数据库中提取相关的 airNodes,并将它们与 relNodes.toNode = airNodes.id 的 relNodes 连接起来(toNode 和 id 是它们各自的字段节点)。然后,我们将这些 relAirNodes 与 edNodes 连接起来,语句 returns 具有以下结构:
[ { 'edNode':..., 'relAirNodes':[{...},{...}] },...]
所以本质上,我们得到了一对数组,其中每一对由一个 edNode 和一组 relAirNode 组成。
问题
relAirNodes 数组中的每个 relAirNode 都有一个 endTime 和 startTime 字段。有没有办法 运行 查询使得 return 结果是一个对数组,对的第一个元素是一个 editNode,对的第二个元素是一个具有 relAirNodes 数组的最小开始时间和 relAirNodes 数组的最大结束时间的单个结构? 换句话说,return 对象看起来像:
[ { 'edNode':..., 'relAirNodes':{'startTime':..., 'endTime':...}}, ...]
Couchbase 连接从左到右。如果您只查找 INNER JOINS,则仅 re-arrange JOIN,这样它可以更早地消除。
创建此处描述的索引https://blog.couchbase.com/ansi-join-support-n1ql/
SELECT en.*, c AS relAirNodes
FROM (SELECT rn.fromNode, MIN(b.startDateTime) AS startDateTime, MAX(b.endDateTime) AS endDateTime
FROM (SELECT an.id, an.customAttributes.endDateTime, an.customAttributes.startDateTime
FROM my_bucket AS an
WHERE an.type = "airNode"
AND an.customAttributes.endDateTime BETWEEN CLOCK_UTC() AND DATE_ADD_STR(CLOCK_UTC(), 14, "day")
) AS b
JOIN my_bucket AS rn ON rn.type = "relNode" AND rn.toNode = b.id
GROUP BY rn.fromNode) AS c
JOIN my_bucket AS en ON en.type = "edNode" AND en.id = c.fromNode
;
CREATE INDEX ix1 ON my_bucket(customAttributes.endDateTime, customAttributes.startDateTime, id) WHERE type = "airNode";
CREATE INDEX ix2 ON my_bucket(toNode, fromNode) WHERE type = "relNode";
CREATE INDEX ix3 ON my_bucket(id) WHERE type = "edNode";
如果需要外部连接(需要 CB 6.5.0+ https://blog.couchbase.com/ansi-join-enhancements-and-ansi-merge/)
SELECT en.*, c AS relAirNodes
FROM my_bucket AS en
LEFT JOIN (SELECT rn.fromNode, MIN(b.startDateTime) AS startDateTime, MAX(b.endDateTime) AS endDateTime
FROM (SELECT an.id, an.customAttributes.endDateTime, an.customAttributes.startDateTime
FROM my_bucket AS an
WHERE an.type = "airNode"
AND an.customAttributes.endDateTime BETWEEN CLOCK_UTC() AND DATE_ADD_STR(CLOCK_UTC(), 14, "day")
) AS b
JOIN my_bucket AS rn ON rn.type = "relNode" AND rn.toNode = b.id
GROUP BY rn.fromNode) AS c ON en.id = c.fromNode
WHERE en.type = "edNode";
还有ARRAY_MIN()、ARRAY_MAX()函数。例如:ARRAY_MIN(relAirNodes[*].startDateTime) 在对象数组上。
背景
我正在运行进行以下查询(我知道它可能难以阅读,所以我会在之后澄清它在做什么):
SELECT *
FROM `my_bucket` AS a
NEST (
SELECT c.toNode, c.fromNode, d.endDateTime, d.startDateTime
FROM `my_bucket` AS c
JOIN (
SELECT id, customAttributes.endDateTime, customAttributes.startDateTime
FROM `my_bucket`
WHERE type='airNode'
AND customAttributes.endDateTime >= CLOCK_UTC()
AND customAttributes.endDateTime <= DATE_ADD_STR(CLOCK_UTC(), 14, 'day')) AS d ON c.toNode = d.id
AND c.type='relNode') b ON a.id = b.fromNode AND a.type='edNode';
本质上,这里发生的是我们从数据库中提取相关的 airNodes,并将它们与 relNodes.toNode = airNodes.id 的 relNodes 连接起来(toNode 和 id 是它们各自的字段节点)。然后,我们将这些 relAirNodes 与 edNodes 连接起来,语句 returns 具有以下结构:
[ { 'edNode':..., 'relAirNodes':[{...},{...}] },...]
所以本质上,我们得到了一对数组,其中每一对由一个 edNode 和一组 relAirNode 组成。
问题
relAirNodes 数组中的每个 relAirNode 都有一个 endTime 和 startTime 字段。有没有办法 运行 查询使得 return 结果是一个对数组,对的第一个元素是一个 editNode,对的第二个元素是一个具有 relAirNodes 数组的最小开始时间和 relAirNodes 数组的最大结束时间的单个结构? 换句话说,return 对象看起来像:
[ { 'edNode':..., 'relAirNodes':{'startTime':..., 'endTime':...}}, ...]
Couchbase 连接从左到右。如果您只查找 INNER JOINS,则仅 re-arrange JOIN,这样它可以更早地消除。
创建此处描述的索引https://blog.couchbase.com/ansi-join-support-n1ql/
SELECT en.*, c AS relAirNodes
FROM (SELECT rn.fromNode, MIN(b.startDateTime) AS startDateTime, MAX(b.endDateTime) AS endDateTime
FROM (SELECT an.id, an.customAttributes.endDateTime, an.customAttributes.startDateTime
FROM my_bucket AS an
WHERE an.type = "airNode"
AND an.customAttributes.endDateTime BETWEEN CLOCK_UTC() AND DATE_ADD_STR(CLOCK_UTC(), 14, "day")
) AS b
JOIN my_bucket AS rn ON rn.type = "relNode" AND rn.toNode = b.id
GROUP BY rn.fromNode) AS c
JOIN my_bucket AS en ON en.type = "edNode" AND en.id = c.fromNode
;
CREATE INDEX ix1 ON my_bucket(customAttributes.endDateTime, customAttributes.startDateTime, id) WHERE type = "airNode";
CREATE INDEX ix2 ON my_bucket(toNode, fromNode) WHERE type = "relNode";
CREATE INDEX ix3 ON my_bucket(id) WHERE type = "edNode";
如果需要外部连接(需要 CB 6.5.0+ https://blog.couchbase.com/ansi-join-enhancements-and-ansi-merge/)
SELECT en.*, c AS relAirNodes
FROM my_bucket AS en
LEFT JOIN (SELECT rn.fromNode, MIN(b.startDateTime) AS startDateTime, MAX(b.endDateTime) AS endDateTime
FROM (SELECT an.id, an.customAttributes.endDateTime, an.customAttributes.startDateTime
FROM my_bucket AS an
WHERE an.type = "airNode"
AND an.customAttributes.endDateTime BETWEEN CLOCK_UTC() AND DATE_ADD_STR(CLOCK_UTC(), 14, "day")
) AS b
JOIN my_bucket AS rn ON rn.type = "relNode" AND rn.toNode = b.id
GROUP BY rn.fromNode) AS c ON en.id = c.fromNode
WHERE en.type = "edNode";
还有ARRAY_MIN()、ARRAY_MAX()函数。例如:ARRAY_MIN(relAirNodes[*].startDateTime) 在对象数组上。