N1QL 对嵌套数组的不同查询

N1QL Distinct Query on Nested Arrays

(Couchbase 4.5) 假设我的 couchbase 实例中存储了以下对象:

{
  parentArray : [
    {
      childArray: [{value: 'v1'}, {value:'v2'}]
    }, 
    {
      childArray: [{value: 'v1'}, {value: 'v3'}]
    }
  ]
}

现在我想 select 来自 childArray 的不同元素,它应该 return 一个等于 ['v1'、'v2'、'v3']。

对此我有几个解决方案。我的第一个想法是继续使用 UNNEST 操作:

SELECT DISTINCT ca.value FROM `my-bucket` AS b UNNEST b.parentArray AS pa UNNEST pa.childArray AS ca WHERE _class="someclass" AND dataType="someDataType";

通过这种方法,我得到了扫描元素数量的多项式爆炸(由于两个数组的未嵌套),并且查询需要一些时间才能完成(对于我的真实数据而言,顺序为24 秒)。当我删除 unnest 并简单地查询顶级元素(那些与 parentArray 相邻的元素)上的不同元素时,它需要毫秒的数量级。

另一种解决方案是在应用程序代码中处理此问题,方法是简单地遍历 returned 值并自行查找不同的值。这种方法不好,因为它给应用程序带来了太多数据 space.

请帮忙!

谢谢!

更新:看起来没有 "WHERE" 子句使用 "UNNEST" 语句性能很快。那么我这里需要数组索引吗?

UPDATE:不用管之前的更新,因为where 子句中没有索引元素。此外,但我确实注意到,如果我删除 UNNEST 或 WHERE,那么查询会很快。此外,查看解释并为复合索引 (_class, dataType) 添加 GSI 我可以在提供的索引上看到 "IndexScan"。

INSERT INTO default values("3",{ "parentArray" : [ { "childArray": [{"value": 'v1'}, {"value":'v2'}] }, { "childArray": [{"value": 'v1'}, {"value": 'v3'}] } ] });

SELECT ARRAY_DISTINCT(ARRAY v.`value` FOR v WITHIN parentArray END) FROM default;

SELECT ARRAY_DISTINCT(ARRAY_FLATTEN(
  ARRAY ARRAY v.`value` FOR v IN ca.childArray END FOR ca IN parentArray END,
  2)) FROM default;

您可以添加 where 子句。如果这需要跨文档使用以下内容。

INSERT INTO default values("4",{ "parentArray" : [ { "childArray": [{"value": 'v5'}, {"value":'v2'}] }, { "childArray": [{"value": 'v1'}, {"value": 'v3'}] } ] });
SELECT ARRAY_DISTINCT(ARRAY_FLATTEN(ARRAY_AGG(ARRAY v.`value` FOR v WITHIN parentArray END),2)) FROM default;
SELECT ARRAY_DISTINCT(ARRAY_FLATTEN(ARRAY_AGG(ARRAY_FLATTEN(ARRAY ARRAY v.`value` FOR v IN ca.childArray END FOR ca IN parentArray END,2)),2)) FROM default;