计算与条件匹配的同一表中的其他文档

时间:2018-02-14 10:42:54

标签: couchbase n1ql

我收到了这个问题:

new_pts=np.float32([ul,ur,br,bl]) #new pts=[[2,0],[2,1122],[1390,1122],[1390,0]]

我希望如此:

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"
  },
  ...
]    

我做错了什么?我已经用Google搜索了这一点,但我无法在N1QL中找到任何明确的计数子查询说明,因此任何文档链接都将受到高度赞赏。

UPD:

我根据@prettyvoid的答案更新了我的代码。我还创建了最小的示例桶来演示问题。

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

Sorry, I don't know how to export buckets from CB

结果如下:

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

2 个答案:

答案 0 :(得分:2)

任何select语句都会产生一个包含内部对象的数组,这是正常的。如果要获得预期结果,请将范围放入数组[0]

中的count对象

修改:以下查询会做您想做的事情,我不确定是否有更好的方法

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

答案 1 :(得分:0)

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

是o.k.仅列出具有非零数量子项的文档?在这种情况下,您可以将此写为聚合查询,其中您将每个子项连接到其父项,并按父项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,请在每个查询的选择列表中添加更多字段或“*”。