[英]Elixir: Using Absinthe to query Dgraph, a graph database. GraphQL to GraphQL+ mapping
我正在使用苦艾酒來構建GraphQL API。 數據存儲區為Dgraph ,它使用GraphQL +作為查詢語言。 它與GraphQL相似,但不相同。
從理論上講,這將使我處於一個美好的境地。 像GraphQL查詢
query {
user {
id
username
posts {
title
text
comments {
text
}
}
}
}
也可能只是Dgraph中的一個查詢。 看起來幾乎相同:
{
users(func: has(type_user))
{
id
username
posts {
title
text
comments {
text
}
}
}
}
我想使用圖數據庫一次加載復雜關系的強大功能。 問題就在於:在苦艾酒中,該模式應該是可組合的。 在模式中將有一個:user
對象,該對象具有:posts
字段,該字段將是list_of(:post
)。 然后是:post
對象。 等等
為了防止N + 1查詢,您可以使用數據加載器或批量加載。
現在,我可以一次性加載所有內容。 例如,我可以編寫一個解析器來做到這一點:
defmodule MyApp.Resolvers.User do
alias MyApp.Users
def users(_, _args, _) do
{:ok, Users.all()}
end
end
以及實際查詢數據庫的用戶上下文
defmodule MyApp.Users do
alias MyApp.Users.User
def all do
query = """
{
users(func: has(type_user))
{
id
username
posts {
title
text
comments {
text
}
}
}
}
"""
case ExDgraph.query(conn(), query) do
{:ok, msg} ->
%{result: %{users: users}} = msg
Enum.map(users, fn x -> struct(User, x) end)
{:error, _error} ->
[]
end
end
end
這里的問題是我超買。 我總是查詢所有內容,即使我只想要一個用戶列表。 這行得通,但不是很好的性能選擇。 而且我失去了可組合性。
解決方案是,如果我可以訪問解析器中的查詢以了解請求了哪些字段。 然后,我可以使用模式匹配來構建查詢,然后將其發送到Dgraph。 我什至可以擁有一個中央解析器和許多查詢生成器。 但是我需要加入查詢並直接解析它。
這樣有可能嗎? 知道在哪里可以找到有趣的解決方案嗎? 也許使用苦艾中間件?
謝謝!
我想我找到了解決方案。 讓我們來一個為您提供用戶列表的解析器。 像這樣:
object :user_queries do
field :users, list_of(:user) do
resolve fn _parent, _, resolution ->
IO.inspect(resolution.definition.selections)
{:ok, Users.all()}
end
end
end
如果您使用類似以下的嵌套查詢命中它:
{
users {
id
name
posts {
id
title
text
comments {
id
text
}
}
}
}
您將在終端中看到一個復雜的嵌套地圖。 它包含我們需要的所有信息。 選擇包含字段。 每個字段都有一個名稱。 如果它有一個嵌套的對象,它將再次包含一個列表selections
。
現在,我們只需要沿着兔子洞遞歸,為Dgraph查詢收集信息並相應地構建它即可。 並且由於它已經通過了苦艾酒的驗證,因此它似乎是一個不錯的選擇。
有趣的是,如果這樣的方法會導致苦艾酒所帶來的優化問題,例如在已經獲取的對象的內存緩存中……
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.