LoginSignup
21
13

More than 3 years have passed since last update.

Amplifyのqueryでfilterするときのand orなどの書き方

Last updated at Posted at 2020-01-09

書いた経緯

Amplify で自動生成されたqueryのDocsをみていて、自動でandとかcontainsとか自動されていて便利だなと思いつつ、andとorとかの書き方がわからずググっていたのですがすぐみつからず、ああかなこうかなと書いてわかったので同じ感じで迷った方に共有するため書きました。よくよく定義をみたら当たり前の書き方でした。

ググるのではなく、公式のドキュメント
https://aws-amplify.github.io/docs/cli-toolchain/graphql
をちゃんと確認したら書いてました。

記事の対象の方

  • Amplify触り始めて、queryの書き方で試行錯誤している人(私)

既知とする条件(書かないこと)

  • Amplifyの使い方
  • graphqlとは?

本文

以下のようなtypeを定義したとします。


type User @model
{
  id: ID!
  lastName: String!
  firstName: String!
  createdAt: AWSDateTime
}

amplifyが自動で以下のUserリストをとるschemaを作成してくれます。

# by amplify
listUsers(
  filter: ModelUserFilterInput
  limit: Int
  nextToken: String
): ModelUserConnection

filter: ModelUserFilterInputの定義は以下が自動生成されています。

# by Amplify

type ModelUserFilterInput {
  id: ModelIDInput
  lastName: ModelStringInput
  firstName: ModelStringInput
  createdAt: ModelStringInput
  and: [ModelUserFilterInput]
  or: [ModelUserFilterInput]
  not: ModelUserFilterInput
}

ここで以下のシンプルなフィルター使用したqueryを書きます。


# 自分で定義
query listUsers($input: ModelUserFilterInput ){
  listUsers(filter: $input) {
    items {
      firstName
      lastName
      createdAt
    }
  }
}

そして変数に値を入力します。まずシンプルなものです。

サンプルデータとして
firstNameにTaro
lastNameにYamada
で1件だけ登録しておきます。

fistNameにTaroが含まれるものを取得します。


# 自分で定義
{
  "input": {
    "firstName": {
      "contains": "Taro"
    }
  }
}

結果

{
  "data": {
    "listUsers": {
      "items": [
        {
          "firstName": "Taro",
          "lastName": "Yamada",
          "createdAt": "2020-01-09T15:37:22.819Z"
        }
      ]
    }
  }
}


and or を使ったquery

以下のように書きます。Docsの定義をみるかぎり
[ModelUserFilterInput]とあるので配列を与えるので
以下のようになります。


{
  "input": {
    "and": [ #andを先に書く!
      {
        "firstName": {
          "contains": "T"
        }
      },
      {
        "lastName": {
          "eq": "Yamada"
        }
      }
    ]
  }
}

結果は先ほどと同じです。
同様にor


{
  "input": {
    "or": [
      {
        "firstName": {
          "contains": "T"
        }
      },
      {
        "firstName": {
          "contains": "K"
        }
      }
    ]
  }
}

で結果は同じです。

以上です。

蛇足

本文とあんまり関係ないですが、andとかorをさきにかくと関数みたいなのにeqとかは違うのが感覚的に迷いました。

Clojureなら(関数 値)で一貫してますが

clojure
;includesのあとにfirstName
(and 
  (includes?
    (.firstName "T")
  (=
    (.lastName "Yamada"))

graphql(Amplify?)の場合はcontainsは変数のあと、andは先にくるのが感覚的に分かり難かったです。

graphql
#amplifyの場合 containsはfirstNameのあと
    "and": [ 
      {
        "firstName": {
          "contains": "T"
        }
      },
      {
        "lastName": {
          "eq": "Yamada" 
        }
      }
    ]

21
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
13