6

私は mysql を使用して meteor で react-apollo を使用し、続編を作成しています。私はまだ JS の初心者です。apollo-server に次のリゾルバ機能があると仮定しましょう:

 export default resolvers = {
     Query: {
         posts(_, args){
             return Post.findAndCountAll({ where: args   });
         },
         numberOfPosts(){
             return /// the number of selected posts
         }
     }

いくつかの条件が満たされたデータベースからいくつかのデータを選択し、選択された行の数を数えてフィールド「numberOfPosts」に返したいと思います。 findAndCountAll()選択した行とカウントを含むオブジェクトを返します。post()選択した行のみを返すようにし、選択した投稿の数のみを返すように numberOfPosts() を取得したいと思います。現在、両方とも posts() によって返されます。

私のスキーマは次のとおりです。

 type Post {
  id: Int
  date: Float
  text: String
}

 type NumberOfPosts{
  total: Int
  filtered: Int
}

type Query {
  posts(
   id: Ind,
   offset: Int,
   limit: Int,
   filter: String): [Post]
  numberOfPosts:[NumberOfPosts] 
}

schema {
  query: Query
}

目標は、次の形式でデータを受け取ることです。

{
  "data": {
    "numberOfPosts": [
      {
        "total": 1000,
        "filtered": 21
      }
    ],
    "posts": [
      {
        "id": 4,
        "date": 5105626122,
        "text": "jzybiwutudi"
      },
      ...
    ]
  }
}

これまでの私の仕事: 1 を試してください:

  let selectedCount;
export default resolvers = {
    Query: {
        posts(_, args){
            return Post.findAndCountAll({where: args}).then(
                function (results) {
                    selectedCount = results.count;
                    return results.rows
                });
        },
        numberOfPosts(){
            return selectedCount
        }
    }}

そのため、リゾルバーの外部で補助変数を定義し、それを選択した行の数に設定すると、 でカウントが返されますnumberOfPosts()。これは機能しますが、これに関する問題はreturn results.rows、エラーが発生することであり、理由がわかりません。

別の問題は、それselectedCountは常に前の行数です

トライ2

うまくいくと思われる別の解決策は、次のように、GraphQL クエリに引数を 2 回渡すことです。

{
  numberOfPosts(filter: "example") {
    total
    filtered
  }
  posts(filter: "example") {
    id
    date
    text
  }
}

次に、両方のリゾルバー関数が同じ引数を認識しているため、同じ投稿を選択してカウントできます。しかし、これは私には正しくないように見えます.同じ引数を2回渡す必要があるため、それらも2回送信されます...

4

1 に答える 1

6

設計と、これらの各クエリが何をすべきかについてもっと考える必要があります。これらのクエリは、データベースまたはグローバル状態を変更するべきではありません。

あなたができる最善のことは、最初の試みと同様に、投稿のリストと同様に、totalとを含む新しいタイプを単純に定義するfilteredことです。NumberOfPosts

したがって、スキーマは次のようになります。

type Post {
  id: Int
  date: Float
  text: String
}

type PostList {
  total: Int
  filtered: Int
  posts: [Post]
}

type Query {
  posts(
    id: Ind,
    offset: Int,
    limit: Int,
    filter: String): PostList
}

schema {
  query: Query
}

そして、あなたは次postsのように解決します:

posts(_, args) {
  return Post.findAndCountAll({ where: args }).then(result => {
    return {
      total: 1000,
      filtered: result.count,
      posts: result.rows
    }
  })
}

合計数に 1000 を入れていることに注意してください。では行の総数を取得できませんfindAndCountAll。その場合は、2 つの異なるクエリを並行して実行しPromise.all、それらが解決されるまで待機する必要があります。

posts(_, args) {
  return Promise.all([
    Post.count(),
    Post.findAndCountAll({ where: args })
  ]).then(data => {
    return {
      total: data[0],
      filtered: data[1].count,
      posts: data[1].rows
    }
  })
}

上記のコードは、 ES6 の destructuring の恩恵を受けることもできます:

posts(_, args) {
  return Promise.all([
    Post.count(),
    Post.findAndCountAll({ where: args })
  ]).then(([totalCount, filteredData]) => {
    return {
      total: totalCount,
      filtered: filteredData.count,
      posts: filteredData.rows
    }
  })
}

これで実行できます:

query {
  posts(filter:"example") {
    total
    filtered
    posts {
      id
      date
      text
    }
  }
}

そして得る:

{
  "data": {
    "posts": {
      "total": 1000,
      "filtered": 21,
      "posts": [
        {
          "id": 4,
          "date": 5105626122,
          "text": "jzybiwutudi"
        },
        ...
      ]
    }
  }
}
于 2017-01-05T05:05:40.643 に答える