graphql-anywhere-mongodb
WARNING: This repo is just an experiment, do not use this in production yet.
A library based off graphql-anywhere that lets you use schemaless GraphQL queries to query documents across one or more MongoDB collections. Use it together with graphql-tag.
Install using npm:
npm install --save graphql-tag graphql-anhywhere-mongodb
Or using yarn:
yarn add graphql-tag graphql-anywhere-mongodb
Example App
Wanna take this for a spin? See the graphql-anywhere-mongodb-example repo for instructions on how to plug this in with graphql-anywhere-mongodb-express to be able to make queries into MongoDB using GraphiQL.
Usage
Use one of the factory functions to create a query executor and then call find
or findOne
with a GraphQL query that contains one or more queries around your mongo collections:
;; { // Can acquire a GraphQLMongoQueryExecutor by passing in a MongoDB URI // this will use the mongo driver to create its own connection const mongo = await graphql; // Alternatively you can use an existing mongo driver connection const myConnection = await ; const mongo = graphql; // Then you can start querying mongodb using graphql queries and the // gql string template from the graphql-tag library const query = gql` { users (limit: $limit, skip: $offset) { firstName lastName age (gte: $age) lastLoggedIn (gt: $date) address { city state zip } } } `; const variables = age: 21 limit: 100 offset: 0 date: '2017-01-17T05:00:00.000Z' ; const results = await mongo;}
Examples
Querying one or more collections
Top level objects correspond to collections. You can query one or more collections in a single graphql query. For example, assuming we have a collection users
and places
, we can make the following query:
# Return firstName and lastName from users# AND also return name from places{ users { firstName lastName } places { name }}
Projection
Every field name listed will be included in the final projection that you get from MongoDB. This works on nested objects AND arrays. The MongoDB _id
field is always returned.
{ users { firstName lastName address { line1 line2 city state zip } favoritePlaces { name gps { lat lng } } }}
In cases where you need to filter on a nested object but project the entire outer document you may add include: true
to the parent document to include it in its entirety. For example, given the same schema as the above query, this would return the entire address
sub-document, even though we only explicitly call out zip
:
{ users { firstName lastName address (include: true) { zip (eq: "33326") } }}
Limit/Skip
You can add a top-level argument for limit
and/or skip
to pass those arguments along to the final mongodb query.
{ users (limit: 10, skip 0) { firstName lastName }}
Sorting
In order to sort by one or more field, annotate the given field with the @sort
directive for sorting in ascending order or the @sortDesc
directive for sorting in descending order on that field.
{ users (limit: 10, skip 0) { firstName lastName age (gte: 21) @sortDesc }}
Filters
Use standard MongoDB filters like $eq
, $ne
, $gt
, $gte
, etc. without the $
prefix as part of your GraphQL query to add filters to your query. See the MongoDB Docs for the full list of valid filters.
Note: Array filters like $elemMatch
are not currently supported.
{ users (limit: 10, skip: 0) { firstName lastName age (gte: 21) address { city (eq: "Miami") state (eq: "Florida") } }}
TODO List
- Support basic querying capabilities against MongoDB Collections.
- Support collection-level things like
limit
andskip
. - Support sorting.
- Support querying on an inner nexted document while projecting the entire document.
- Support more complex data types
- Support projection of arrays inside documents.
- Support filtering of arrays inside documents.
- GraphiQL-like example to test this against arbitrary MongoDB instances.
- Support mutating documents
- Support inserting documents