簡単なことだと思いますが、GraphQLのドキュメントにもGraphcoolのドキュメントにも何も見つかりませんでした。
このスキーマを持つエンティティがあるとします(新しいGraphQLユーザー、スキーマ表現を間違えた場合は申し訳ありません)。
_Book {
name: String!
author: String!
categories: [String!]
}
_
_"mystery"
_カテゴリの一部であるすべての書籍に対してクエリを実行するにはどうすればよいですか? allBooks(filter: {})
でフィルタリングできることはわかっていますが、_categories_in: ["mystery"]
_と_categories_contains: "mystery"
_ではうまくいきませんでした。
Category
モデルこの状況についてもう少し考えてみると、Category
モデルを作成するのは間違いありません。
たとえば、読者がお気に入りのカテゴリを後で購読できるようにしたいとします。または、既存のすべてのカテゴリのリストが必要な場合はどうなりますか?文字列リストを使用して、すべての書籍をクエリし、取得したすべてのカテゴリを何らかの方法で後処理する必要があります。文字列リストを使用するのではなく、モデルレベルでこれを処理する方がはるかに自然に感じられます。
代わりに、新しいCategory
モデルを作成し、Category
とBook
の間に多対多の関係を追加できます。このような状況では、一意の列挙フィールドtag
と文字列フィールドtext
を追加します。 (一意の文字列フィールドtag
だけでも適切でしょう。おそらく好みの問題です。)
この設定により、次のようなデータ要件を簡単に満たすことができます
どの書籍が特定のカテゴリに割り当てられていますか?
query {
# query books by unique category tag
Category(tag: MYSTERY) {
books {
id
}
}
# query books by specific category text
Category(filter: {
text: "mystery"
}) {
books {
id
}
}
}
特定のリストの少なくとも1つのカテゴリに割り当てられている書籍はどれですか?
query {
allCategories(filter: {
OR: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
指定されたリストのすべてのカテゴリに割り当てられている本はどれですか?
query {
allCategories(filter: {
AND: [{
tag: MYSTERY
}, {
tag: MAGIC
}]
}) {
books {
id
}
}
}
上記のクエリは指定されたデータ要件を満たしていますが、書籍はレスポンスでCategory
によってグループ化されるため、クライアントのグループをフラット化する必要があります。
いわゆる関連フィルターを使用すると、その関連カテゴリーを定義した条件に基づいて本のみを取得するようにそれを変えることができます。
たとえば、クエリ指定されたリストの少なくとも1つのカテゴリに割り当てられた本の場合:
query {
allBooks(filter: {
OR: [{
categories_some: {
tag: MYSTERY
},
categories_some: {
tag: MAGIC
}
}]
}) {
id
}
}
ホストされたGraphQLサービスの使用に関心がある場合は、 scaphold.io がしばらくの間この機能を備えています。 APIのすべての接続フィールドにはWhereArgs
引数が付いており、実際にデータを掘り下げることができるフィルターを公開しています。このようなスカラーのリストがある場合、WhereArgsにはcontains
&notContains
フィールドが含まれ、リスト内の値に基づいて結果をフィルタリングできます。これにより、このようなクエリを作成できます。
query MysteriousBooks($where:BookWhereArgs) {
viewer {
allBooks(where:$where) {
edges { node { title, ... } }
}
}
}
# Variables
{
"where": {
"categories": {
"contains": "mystery"
}
}
}
完全にするために、スカラーリストでフィルタリングする必要なしに、これを機能させるためにわずかなスキーマ再調整を行うこともできます。たとえば、Category
をノード実装タイプにして、Category
とBook
の間の接続を作成できます。 Book
には多くのカテゴリがありませんが、次のようなクエリを発行できます。
query MysteriousBooks($where: CategoryWhereArgs) {
viewer {
allCategories(where: $where) {
books {
edges { node { title, ... } }
}
}
}
}
# Variables
{
"where": {
"name": {
"eq": "mystery"
}
}
}
この方法でスキーマを構造化すると、アーカイブ内のすべての本をループ処理する必要なく、カテゴリ内の本をさらにフィルタリングできます。例えば。 「昨年に書かれたすべての謎の本」を効率的に求めることができます。
完全な開示:私はScapholdで働いていますが、切り替えない場合は難しい気持ちで試してみることをお勧めします。 GraphQLを試し、愛する人々に出会えるのを楽しみにしています。このタイプの動作を自分のサーバーに実装する方法に興味がある場合は、私に知らせてください。また、そこでサポートさせていただきます。
これが役に立てば幸いです!