Which syntax for filtering queries in Graphiql?
Asked Answered
C

1

11

New to graphql and started playing with graphiql. I have a Product data type

  type Product {
    _id: String
    name: String
    price: Float
  }

I have mongodb populated with some products

{ "_id" : ObjectId("5a61b31e009c0bef5d724a47"), "name" : "GROUND COFFEE", "price" : 3.06 }
{ "_id" : ObjectId("5a61b31e009c0bef5d724a48"), "name" : "PORK SAUSAGES 500g",  "price" : 4.39 }
{ "_id" : ObjectId("5a61b31e009c0bef5d724a49"), "name" : "MILK UHT 1LT", "price" : 1.29 }
{ "_id" : ObjectId("5a61b31e009c0bef5d724a4a"), "name" : "HEINEKEN PREMIUM LIGHT 33CL", "price" : 1.61 }

In graphiql I can execute a query like this

query {
  products{
     name,
    price
  }
}

Query result is

{
  "data": {
    "products": [
      { "name" : "GROUND COFFEE", "price" : 3.06 },
      { "name" : "PORK SAUSAGES 500g",  "price" : 4.39  },
      { "name" : "MILK UHT 1LT", "price" : 1.29 },
      { "name" : "HEINEKEN PREMIUM LIGHT 33CL", "price" : 1.61 }
    ]
  }
}

Wow, that's fine. So next step is: now I want only products with price greater than 2.0 And I face two problems I do not know how to solve

1) Which is the correct syntax to implement filtering?
2) How comparison operators have to be specified? And how this specification maps to mongodb comparison operators?

I tried with

query {
  products(filter:{price: {gt:2.0} }){
     name,
    price
  }
}

but I get an error for "filter":

Unknown argument "filter" on field "products" of type "Query". I find no way to do this ...

UPDATE @diego

const typeDefs = [`
  type Query {
    product(_id: String): Product
    products: [Product]
  }

  type Product {
    _id: String
    name: String
    price: Float
  }

  type Mutation {
    createProduct(name: String, price: Float): Product
  }

  schema {
    query: Query
    mutation: Mutation
  }
`];

const resolvers = {
  Query: {
    product: async (root, {_id}) => {
      return prepare(await Products.findOne(ObjectId(_id)))
    },
    products: async () => {
      return (await Products.find({}).toArray()).map(prepare)
    },
  },
  Mutation: {
    createProduct: async (root, args, context, info) => {
      const res = await Products.insert(args)
      return prepare(await Products.findOne({_id: res.insertedIds[1]}))
    },
  },
}
Cutwork answered 19/1, 2018 at 11:34 Comment(1)
AFAIK, you should have a query defined in GraphQL that accepts a filter and uses it to filter mongo results. Can you show the resolver for products?Camellia
C
10

First you would need to change the Query type definition

products(filter: String): [Product]

Now it accepts a string filter and you can use it in the resolver

products: async (_, {filter}) => {
  const query = JSON.parse(filter)
  return (await Products.find(query).toArray()).map(prepare)
}

Then you can call your query like:

query {
  products(filter: "{\"price\": {\"gt\":2.0} }") {
    name,
    price
  }
}

I do not know if there is a way to do this without changing the query itself.

Camellia answered 19/1, 2018 at 13:16 Comment(1)
Ok, now it works (change gt to $gt). Anyway both resolver and query language depend on the backend used. Is there any way to avoid this?Cutwork

© 2022 - 2024 — McMap. All rights reserved.