代码之家  ›  专栏  ›  技术社区  ›  Tr1gZer0

嵌套数组上的N1QL非重复查询

  •  0
  • Tr1gZer0  · 技术社区  · 9 年前

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

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

    childArray

    我有几个解决方案。我的第一个想法是继续使用 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相邻的元素)上的不同元素时,它会以毫秒为单位。

    另一种解决方案是在应用程序代码中处理这个问题,只需遍历返回的值并自己查找不同的值。这种方法很糟糕,因为它将太多数据带入了应用程序空间。

    请帮忙!

    1 回复  |  直到 9 年前
        1
  •  3
  •   vsr    9 年前
    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;