簡體   English   中英

Elixir:使用苦艾酒查詢圖形數據庫Dgraph。 GraphQL到GraphQL +映射

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM