2017-02-13 5 views
1

ネスト内でのネスト。 私は、次のレストランの例に私のニーズに適応しました:Couchbase N1QL - ネスト内でのネスト

所望の出力:

{ 
    "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; 

but:
1.Ob大胆にネストされたネストがありません
2.返された順序が間違っています - 飲み物のネストが最後のものではなく
(3。私も同期のゲートウェイを使用しているので - それは、すべてのドキュメントとすべての「_sync」のフィールドを返します - 各ドキュメントでこれを省略する方法を見つけ出すことはできません)

UPDATE 1:適応SOLUTION
NB:。私はメイン成分IDを保持することはできません上記を指定する必要があります。

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'第二の溶液もよさそうだ - このクエリは、主電源が食材を経て発見されることを必要とするので、残念ながらそれは私の場合は動作しません。私の必要性のために、メインは何の成分もなく存在することができます。 編集:>彼は別の解決策を思いついた。最終的な解決策

だから、もう一度、geraldss'助けを借りて、私はキーを追跡するために、追加のドキュメントを必要としない解決策があります:2.

UPDATE 2を参照してください

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 
; 

NBを - AND meta().id NOT LIKE '_sync:%'行は、同期ゲートウェイを使用する場合にのみ必要です。

ただ1つのキーで、関連するすべてのドキュメントを引き出すことができます。たとえそれらが直接の親には不明であっても可能です。
geraldssありがとうございます。

答えて

関連する問題