嵌套在Nest中。 我已将我的需求调整到以下餐厅示例中:
期望的输出:
{
"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
}
}
示例文档:
// RESTAURANTS
{
"id": "restaurant1",
"type": "restaurant",
"name": "Foodie",
"drinkIds": [ "drink1", "drink2" ],
"mainIds: [ "main1", "main2" ]
},
// MAINS
{
"id": "main1",
"type": "main",
"restaurantIds": [ "restaurant1" ],
"title": "Steak and Chips"
},
{
"id": "main2",
"type": "main",
"restaurantIds": [ "restaurant1" ],
"title": "Fish and Chips"
},
// INGREDIENTS
{
"id": "ingredient1",
"type": "ingredient",
"title": "steak",
"mainIds": [ "main1" ]
},
{
"id": "ingredient2",
"type": "ingredient",
"title": "chips",
"mainIds": [ "main1", "main2" ]
},
{
"id": "ingredient3",
"type": "ingredient",
"title": "fish",
"mainIds": [ "main2" ]
},
// DRINKS
{ you get the idea.... }
我能得到的最接近的是:
SELECT restaurant, mains, drinks
FROM default restauant USE KEYS "restaurant1"
NEST default mains ON KEYS restaurant.mainIds
NEST default drinks ON KEYS restaurant.drinkIds;
但:
显然嵌套的巢遗失了
2.退回的订单不正确 - 首先是饮料巢而不是最后一个
(3.由于我也使用Sync Gateway - 它会返回每个文档的所有&#34; _sync&#34;字段 - 无法弄清楚如何在每个文档中省略此内容。)
更新1:适应性解决方案
注意:我应该在上面指出 main 不能保存 ingredientIds 。
基于杰拉德斯&#39;在下面的有用输入中,我添加了一个跟踪每家餐厅密钥的文档,例如:
{
"id": "restaurant1-JoeBloggs",
"dinerId": "JoeBloggs",
"ingredientIds": [ "ingredient1", "ingredient2" "ingredient3" ],
"mainOrdered": [ "main1" ], // < other potential uses...
"drinkOrdered": [ "drink2" ]
}
我将此添加到geraldss&#39;下面的第一个解决方案作为JOIN使其可用于查询,例如:
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&#39;下面的第二个解决方案也看起来不错 - 不幸的是它不适用于我的情况,因为这个查询要求通过配料找到主电源;为了我的需要,主要可以存在,没有任何成分。 编辑:&gt;他提出了另一个解决方案。见2.
更新2:最终解决方案
所以,再次,与杰拉德斯&#39;帮助我有一个解决方案,不需要额外的文档来跟踪密钥:
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
;
注意 - 仅在使用Sync Gateway时才需要AND meta().id NOT LIKE '_sync:%'
行。
只需1个密钥,我就可以提取所有相关文档 - 即使他们不知道直接的父母&#39;。 谢谢geraldss。
答案 0 :(得分:1)
如果主电源包含ingredientIds:
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
;
编辑:已更新,其中包含未被任何成分引用的主电源。
如果主电源不包含ingredientIds:
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
;