统计同table中符合条件的其他文档

Count other documents in the same table matching the condition

我有这个查询:

SELECT
    id,
    (
        SELECT COUNT(*)
            FROM default t USE KEYS default.id
            WHERE t.p_id=default.id
    ) as children_count
FROM default
WHERE 1

我希望这样:

[
  {
    "children_count": 5,
    "id": "1"
  },
  ...
]    

但我明白了:

[
  {
    "children_count": [
      {
        "": 0
      }
    ],
    "id": "1"
  },
  ...
]

我做错了什么?我用谷歌搜索了这个,但我找不到任何关于 N1QL 中计数子查询的明确解释,因此非常感谢任何指向文档的链接。

更新:

我已经根据@prettyvoid 的回答更新了我的代码。我还创建了最小示例存储桶来演示该问题。

SELECT
    id,
    (
        SELECT COUNT(*) as count
            FROM test t USE KEYS "p.id"
            WHERE t.p_id=p.id
    )[0].count as children_count
FROM test p
WHERE 1

结果如下:

[
  {
    "children_count": 0,
    "id": 1
  },
  {
    "children_count": 0,
    "id": 2
  },
  {
    "children_count": 0,
    "id": 3
  }
]

任何 select 语句都会为您生成一个包含对象的数组,这很正常。如果您想获得预期的结果,那么范围内到数组 [0]

内的计数对象

编辑:下面的查询会做你想要的,不过我不确定是否有更好的方法

SELECT
    id,
    (
    SELECT COUNT(*) as count
        FROM default t USE KEYS (SELECT RAW meta().id from default)
        WHERE t.p_id=p.id
    )[0].count as children_count
FROM default p

请务必注意,在 Couchbase 中,检索文档的最快方法是通过其文档键。使用 GSI 索引是可行的,但速度较慢。与大多数其他数据库一样,最好避免全面扫描。你说你可以使 id 与文档密钥相同,所以我假设是这种情况,这样我就可以在 on keys 子句中使用 p_id

是吗o.k。仅列出具有 non-zero 个子项的文档?在这种情况下,您可以将其编写为聚合查询,在其中将每个子项连接到其父项,并按父项 ID 分组(注意我的存储桶称为 default):

select p.id, count(*) as children_count from default c join default p on keys c.p_id group by p.id;

如果您需要包括具有零个子文档的文档,您还需要 UNION 查询来查找这些文档。在这种情况下,我们知道:

select raw array_agg(distinct(p_id)) from default where p_id is not null

会给我们一个父 ID 数组,所以我们可以得到不在列表中的 ID:

select id, 0 as children_count from default p where not array_contains( (select raw array_agg(distinct(p_id)) from default where p_id is not null)[0],id);

所以,如果我们 UNION 两个:

(select p.id, count(*) as children_count from default c join default p on keys c.p_id group by p.id) UNION (select id, 0 as children_count from default p where not array_contains( (select raw array_agg(distinct(p_id)) from default where p_id is not null)[0],id));

我们得到所有 ID 及其 children_count 的列表,无论是否为零。如果您想要的不仅仅是 ID,请在每个查询的 select 列表中添加更多字段或“*”。