Athul M R
Athul M R

Reputation: 411

GraphQL query on Embedded/Nested Field in MongoDB

How to specify a query condition on fields in an embedded/nested document in MongoDB using GraphQL ?

In mongo shell I can easily get the document by

db.users.find({ 'contacts.phone': '8148*****' } ).pretty();

Which will fetch me the record

{
        "_id" : ObjectId("5c93c0601a29f5183929c02c"),
        "name" : "Athul",
        "contacts" : {
                "address" : "Some address",
                "phone" : "8148*****",
                "email" : "***@live.com"
        },
        "__v" : 0
}

On my GraphQL Schema I have defined the query as mentioned below

...
input ContactsInput {
    address: String
    phone: String
    email: String
}

input userInput {
  name: String
  contacts: ContactsInput
}

type RootQuery {
  users(user: userInput): [User!]!
}
....

The Resolver for users is

...
const User = require('../../models/user');
...
    users: async args => {
        try{
            const query = JSON.parse(JSON.stringify(args.user));
            const userList = await User.find(query);

            if(!userList) {
                throw new Error("No user found");
            }

            return userList;
        } catch(err){
            throw err;
        }
    }
...

(It works fine if I search with the name)

And in GraphiQL I'm trying to get the same record by the below query

query{
  users(user: {contacts: {
    phone: "8148*****" 
  }}){
    name
    contacts{
      email
      phone
    }
  }
}

with which I'm not able to get the same record.

Because at the back end its executing

db.users.find({ contacts: { phone: '8148405590' } });

which is not equivalent to

db.users.find({ 'contacts.phone': '8148*****' } );

Can you please help me resolve this issue ?

Upvotes: 2

Views: 1803

Answers (1)

Marco Daniel
Marco Daniel

Reputation: 5765

It looks like you have to build the query object before sending it to mongodb.

You can try something like:

const tempQuery = {'contacts.phone': args.user.contacts.phone}

const query = JSON.parse(JSON.stringify(tempQuery));

You just have to make sure that all the values(user.contacts.phone) exist in the input, and if you want to have other queries you have to write all different combinations (ex: contacts.email).

Otherwise you could have a look into this blog post about GraphQL to MongoDB and the library graphql-to-mongodb, but to implement it you might have to refactor a bit of your code.

Upvotes: 1

Related Questions