Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Couchbase N1QL-嵌套中的嵌套_Couchbase_N1ql - Fatal编程技术网

Couchbase N1QL-嵌套中的嵌套

Couchbase N1QL-嵌套中的嵌套,couchbase,n1ql,Couchbase,N1ql,在巢中筑巢。 我已将我的需求调整为以下餐厅示例: 期望输出: { "restaurant": { "id": "restaurant1", "name": "Foodie", "mains": [ // < main nested in restaurant { "id": "main1", "title": "Steak and Chips", "in

在巢中筑巢。 我已将我的需求调整为以下餐厅示例:

期望输出:

{
  "restaurant": {
    "id": "restaurant1",
    "name": "Foodie",
    "mains": [                          // < main nested in restaurant
      {
        "id": "main1",
        "title": "Steak and Chips",
        "ingredients": [                // < ingredient nested in main (...which is nested in restaurant)
          {
            "id": "ingredient1",
            "title": "steak"
          },
          {
            "id": "ingredient2",
            "title": "chips"
          }
        ]
      },
      {
        "id": "main2",
        "title": "Fish and Chips",
        "ingredients": [
          {
            "id": "ingredient3",
            "title": "fish"
          },
          {
            "id": "ingredient2",
            "title": "chips"
          }
        ]
      }
    ]
    "drinks": [ you get the idea ]     // < drink nested in restaurant
  }
}
我能得到的最接近无误的结果是:

SELECT restaurant, mains, drinks
FROM default restauant USE KEYS "restaurant1"
NEST default mains ON KEYS restaurant.mainIds
NEST default drinks ON KEYS restaurant.drinkIds;
但是: 1.很明显,嵌套的巢不见了 2.返回的订单不正确-饮料排在第一位,而不是最后一位 3.因为我也在使用同步网关,它会返回每个文档的所有同步字段,所以我不知道如何在每个文档上省略它

更新1:适应的解决方案 注意:我应该在上面指定一个main不能保存ingredentid

基于下面geraldss的v有用输入,我添加了一个跟踪每个餐厅钥匙的文档,例如:

{ 
  "id": "restaurant1-JoeBloggs",
  "dinerId": "JoeBloggs",
  "ingredientIds": [ "ingredient1", "ingredient2" "ingredient3" ],
  "mainOrdered": [ "main1" ],    // < other potential uses...
  "drinkOrdered": [ "drink2" ]
}
我将其添加到geraldss的第一个解决方案中,作为连接,以使其可用于查询,例如:

SELECT *
FROM
(
SELECT
    r.*,
    (
        SELECT
            drink.*
        FROM default AS drink
        USE KEYS r.drinkIds
    ) AS drinks,
    (
        SELECT
            main.*,
            (
                SELECT
                  ingredient.*
                  FROM default AS ingredient
                  USE KEYS keyIndex.ingredientIds   // < keyIndex
                  WHERE ingredient.mainId=main.id
            ) AS ingredients
        FROM default AS main
        USE KEYS r.mainIds
    ) AS mains
FROM default AS r
USE KEYS "restaurant1"
JOIN default AS keyIndex ON KEYS "restaurant1-JoeBloggs"   // < keyIndex JOINed
) AS restaurant
;
geraldss下面的第二个解决方案看起来也不错——不幸的是,它对我的情况不起作用,因为这个查询要求通过成分找到主要成分;为了满足我的需要,可以不加任何配料就有一个主食。编辑:>他想出了另一个解决方案。见第2条

更新2:最终解决方案

因此,再一次,在geraldss的帮助下,我有了一个不需要额外文档来跟踪密钥的解决方案:

SELECT *
FROM
  (
  SELECT
    restaurant.id, restaurant.name,
    (
      SELECT
      drink.id, drink.title
      FROM default AS drink
      USE KEYS restaurant.drinkIds
    ) 
    AS drinks,
    (
      SELECT
      main.id, main.title,
      ARRAY_AGG({"title":ingredient.title, "id":ingredient.id}) AS ingredients
      FROM default AS ingredient
      JOIN default AS main
      ON KEYS ingredient.mainIds
      WHERE main.restaurantId="restaurant1"
      AND meta().id NOT LIKE '_sync:%'                          // < necessary only if using Sync Gateway
      GROUP BY main

      UNION ALL

      SELECT
      mainWithNoIngredients.id, mainWithNoIngredients.title
      FROM default AS mainWithNoIngredients
      UNNEST mainWithNoIngredients AS foo                       // < since this is being flattened the AS name is irrelevant
      WHERE mainWithNoIngredients.restaurantId="restaurant1" 
      AND mainWithNoIngredients.type="main"
      AND meta().id NOT LIKE '_sync:%'                          // < necessary only if using Sync Gateway
      AND META(mainWithNoIngredients).id NOT IN 
      (
        SELECT RAW mainId
        FROM default AS ingredient
      )
    ) 
    AS mains

  FROM default AS restaurant
  USE KEYS "restaurant1"
  ) 
  AS restaurant
;
注意-与meta.id不同的“\u sync:%”行只有在使用同步网关时才是必需的

只需一个键,我就可以提取所有相关的文档,即使直接的“家长”不知道它们。 谢谢geraldss。

如果电源包含以下元件:

SELECT *
FROM
(
SELECT
    r.*,
    (
        SELECT
            drink.*
        FROM default AS drink
        USE KEYS r.drinkIds
    ) AS drinks,
    (
        SELECT
            main.*,
            (
                SELECT
                    ingredient.*
                FROM default AS ingredient
                USE KEYS main.ingredientIds
            ) AS ingredients
        FROM default AS main
        USE KEYS r.mainIds
    ) AS mains
FROM default AS r
USE KEYS "restaurant1"
) AS restaurant
;
SELECT *
FROM
(
SELECT
    r.*,
    (
        SELECT
            drink.*
    FROM default AS drink
    USE KEYS r.drinkIds
    ) AS drinks,
    (
        SELECT
            main.*,
            ARRAY_AGG(ingredient) AS ingredients
        FROM default AS ingredient
        JOIN default AS main
    ON KEYS ingredient.mainIds
        WHERE "restaurant1" IN main.restaurantIds
        GROUP BY main
        UNION ALL
        SELECT
            main.*
        FROM default AS main
        WHERE "restaurant1" IN main.restaurantIds
        AND META(main).id NOT IN (
            SELECT RAW mainId
            FROM default AS ingredient
            UNNEST mainIds AS mainId
        )
    ) AS mains
FROM default AS r
USE KEYS "restaurant1"
) AS restaurant
;
编辑:更新以包括未被任何成分引用的主管道

如果电源不包含IngRadientids:

SELECT *
FROM
(
SELECT
    r.*,
    (
        SELECT
            drink.*
        FROM default AS drink
        USE KEYS r.drinkIds
    ) AS drinks,
    (
        SELECT
            main.*,
            (
                SELECT
                    ingredient.*
                FROM default AS ingredient
                USE KEYS main.ingredientIds
            ) AS ingredients
        FROM default AS main
        USE KEYS r.mainIds
    ) AS mains
FROM default AS r
USE KEYS "restaurant1"
) AS restaurant
;
SELECT *
FROM
(
SELECT
    r.*,
    (
        SELECT
            drink.*
    FROM default AS drink
    USE KEYS r.drinkIds
    ) AS drinks,
    (
        SELECT
            main.*,
            ARRAY_AGG(ingredient) AS ingredients
        FROM default AS ingredient
        JOIN default AS main
    ON KEYS ingredient.mainIds
        WHERE "restaurant1" IN main.restaurantIds
        GROUP BY main
        UNION ALL
        SELECT
            main.*
        FROM default AS main
        WHERE "restaurant1" IN main.restaurantIds
        AND META(main).id NOT IN (
            SELECT RAW mainId
            FROM default AS ingredient
            UNNEST mainIds AS mainId
        )
    ) AS mains
FROM default AS r
USE KEYS "restaurant1"
) AS restaurant
;

嗨,杰拉尔德斯,非常感谢你的解决方案!我采用了您的第一个解决方案,并添加了一个新的索引文档。见上文。在尝试第二种解决方案时,成分返回为空。也许问题出在餐厅1在主餐厅的位置?当我用WHERE-component.type=component替换该行时,它开始工作,尽管我认为可能需要进一步的条件。然而,即使这个查询是完善的,它也不适合我的情况,因为这个查询要求通过成分找到主要成分。在我的例子中,main可以不含任何成分而存在。你可以在子查询中添加一个联合,以拾取不含成分的main。嗨@geraldss。好啊根据你的评论,我一直试图利用UNION建立一个查询,但没有成功。你能给我指出正确的方向吗?如果我能避免用额外的文件来记录钥匙,那就更好了。谢谢你,杰拉尔德斯。我想最不合适的线路是在错误的地方?但是,上面的更新2产生了预期的结果。我在编辑的更新2中也做了一些假设-如果它们不正确或有误导性,请毫不犹豫地编辑我或让我知道。如果没有你的帮助,我是不可能到达那里的!再次感谢。好的,很高兴你有了解决办法。不知道为什么不安对你不起作用。