Couchbase n1ql - 使用索引的 NEST 外部文档

Couchbase n1ql - NEST foreign document using indexes

我正在尝试创建一个 N1QL 查询,该查询将 return 一个客户端列表并嵌入一个 API 键数组。这是我的设置:

:

{
    "Client-a3c1c7f8r89732": {
        "type": "Client",
        "id": "a3c1c7f8r89732",
        "name": "Cognito Inc"
    },
    "Client-z6cc6f4r6feer5": {
        "type": "Client",
        "id": "z6cc6f4r6feer5",
        "name": "Some Corp"
    },
    "ApiKey-3846516546897987": {
        "type": "ApiKey",
        "key": "3846516546897987",
        "client_id": "a3c1c7f8r89732"
    },
    "ApiKey-98765164865351321": {
        "type": "ApiKey",
        "key": "98765164865351321",
        "client_id": "a3c1c7f8r89732"
    },
    "ApiKey-646546846546549887": {
        "type": "ApiKey",
        "key": "646546846546549887",
        "client_id": "a3c1c7f8r89732"
    }
}

可用索引:

CREATE INDEX `idx-client-query` ON `primary`(`type`,`name`,`id`) WHERE (`type` = "Client")
CREATE INDEX `idx-apikey-query` ON `primary`(`type`,`client_id`,`key`) WHERE (`type` = "ApiKey")

所需的 N1QL 查询输出:

[
    {
        "id": "a3c1c7f8r89732",
        "name": "Cognito Inc",
        "api_keys": [
            {
                "key": "3846516546897987"
            },
            {
                "key": "98765164865351321"
            },
            {
                "key": "646546846546549887"
            }
        ]
    },
    {
        "id": "z6cc6f4r6feer5",
        "name": "Some Corp",
        "api_keys": []
    }
]

到目前为止我已经试过了

SELECT client.name, client.id, api_key.* as api_keys
FROM `primary` client
INNER NEST `primary` api_key ON client.id = api_key.client_id
WHERE client.type = 'Client' AND api_key.type = 'ApiKey'

对于类似问题的任何帮助或 link 将不胜感激,谢谢 :)

我认为你在 NEST

的正确轨道上

这是我所做的:

SELECT c.id, c.name, ARRAY { x.`key` } FOR x IN a END AS api_keys
FROM `prim` c
LEFT NEST `prim` a ON c.id = a.client_id
WHERE c.type = "Client";

我添加了一个索引:

CREATE INDEX `adv_client_id` ON `prim`(`client_id`)

您可能想要 LEFT NEST,因为您想要的结果包括一个没有分配 API 键的客户端。

ARRAY { } 语法只会将键提取到您想要的结果中,但您可以执行 SELECT c.id, c.name, a AS api_keys . . . 并获取 ApiKey 文档中的所有值。但我认为无论哪种方式你都需要新索引。

此外,您不需要过滤 api_key.type,因为您只是加入 API 键。

我尝试了 运行 你的 NEST 查询,但我遇到了语法错误(而你说你没有结果),所以我不能确定为什么它没有 return 任何东西(我使用的是 Couchbase 7,仅供参考)

CREATE INDEX ix1 ON default (id, name) WHERE type = "Client";
CREATE INDEX ix2 ON default (client_id, `key`) WHERE type = "ApiKey";

CB 7.0

使用相关子查询。子查询生成 ARRAY

SELECT c.id, c.name,
       (SELECT RAW a.`key`
        FROM default AS a
        WHERE a.type = "ApiKey" AND a.client_id = c.id) AS api_keys
FROM default AS c
WHERE c.type = "Client" AND c.id IS NOT NULL;

CB 7.0 之前

在pre 7.0中,关联子查询有限制(需要USE KEYS)。所以使用 JOIN 和聚合(它可以在两边使用覆盖 vs NEST 不会使用覆盖)。

SELECT c.id, c.name, ARRAY_AGG(a.`key`) AS api_keys
FROM default AS c
LEFT JOIN default AS a ON a.type = "ApiKey" AND a.client_id = c.id
WHERE c.type = "Client" AND c.id IS NOT NULL
GROUP BY c.id, c.name;

尝试使用提示进行哈希连接

apis WITH (SELECT a1.client_id, ARRAY_AGG(a1.`key`) AS api_keys
           FROM default AS a1
           WHERE a1.type = "ApiKey" AND a1.client_id IS NOT NULL
           GROUP BY a1.client_id)
SELECT c.id, c.name, a.api_keys
FROM default AS c
JOIN apis AS a ON a.client_id = c.id
WHERE c.type = "Client" AND c.id IS NOT NULL;

如果数据大小合理

apiobj WITH (OBJECT v.client_id:v.api_keys
             FOR v IN (SELECT a1.client_id, ARRAY_AGG(a1.`key`) AS api_keys
                       FROM default AS a1
                       WHERE a1.type = "ApiKey" AND a1.client_id IS NOT NULL
                       GROUP BY a1.client_id)
             END)
SELECT c.id, c.name, apiobj.[c.id] AS api_keys
FROM default AS c
WHERE c.type = "Client" AND c.id IS NOT NULL;