如何在n1ql查询中从嵌套数组中提取最大值和最小值?

wb1gzix0  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(287)

背景

我正在运行以下查询(我知道它可能很难阅读,所以我会在以后澄清它在做什么):

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连接起来,其中relnodes.tonode=airnodes.id(tonode和id是来自各自节点的字段)。然后,我们将这些relairnodes与ednodes连接起来,语句返回以下结构:

[ { 'edNode':..., 'relAirNodes':[{...},{...}] },...]

所以本质上,我们得到了一个成对的数组,其中每对由一个ednode和一个relairnodes数组组成。

问题

relairnodes数组中的每个relairnode都有一个endtime和starttime字段。有没有一种方法可以运行查询,使返回的结果是一个成对数组,成对的第一个元素是editnode,成对的第二个元素是一个结构,其中relairnodes数组的起始时间最小,relairnodes数组的结束时间最大?换句话说,返回对象看起来像:

[ { 'edNode':..., 'relAirNodes':{'startTime':..., 'endTime':...}}, ...]
wgmfuz8q

wgmfuz8q1#

couchbase连接从左到右。如果只查看内部联接,则只需重新排列联接,使其尽早消除。
创建此处描述的索引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\u min()、array\u max()函数。例如:对象数组上的数组\u min(relairnodes[*].startdatetime)。

相关问题