UNPKG

apongo

Version:

Create Mongo aggregation pipelines with recursive joins for Apollo queries.

97 lines (78 loc) 2.4 kB
import { mergeTypes } from 'merge-graphql-schemas'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { ApolloServer } from 'apollo-server'; import gql from 'graphql-tag'; import mongoose from 'mongoose'; import { apongoDirective } from '../src/types'; import createPipeline from '../src/create-pipeline'; const { apongoDirectiveTypeDefs, apongoDirectiveTransformer } = apongoDirective('apongo'); const userSchema = new mongoose.Schema({ name: String, }) const taskSchema = new mongoose.Schema({ userId: String, task: String, }) export const User = mongoose.model('user', userSchema); export const Task = mongoose.model('task', taskSchema); export const SubTask = mongoose.model('subtask', taskSchema); const sortSubTasks = JSON.stringify({ order: -1 }).replace(/"/g, '\\"'); const types = gql` type User { _id: String name: String } type Task { _id: String task: String user: User @apongo(lookup: { collection: "users", localField: "userId", foreignField: "_id" }) latestSubTask: SubTask @apongo(lookup: { collection: "subtasks", localField: "_id", foreignField: "taskId", sort: "${sortSubTasks}", limit: 1 }) } type SubTask { _id: String order: String } type PaginatedTasks { tasks: [Task!]! count: Int } type Query { tasks: [Task!]! paginatedTasks: PaginatedTasks! } `; const resolvers = { Query: { tasks: (_, args, context, resolveInfo) => { const pipeline = createPipeline(null, resolveInfo, context); return Task.aggregate(pipeline) }, paginatedTasks: async (_, args, context, resolveInfo) => { const pipeline = [ ...createPipeline('tasks', resolveInfo, context), { $facet: { tasks: [{ $limit: 10 }], count: [ { $group: { _id: null, count: { $sum: 1 } } }, ], }, }, ]; // console.log(JSON.stringify(pipeline, null, 2)) return Task.aggregate(pipeline).exec().then(([{tasks, count}]) => { return { tasks, count: count.length === 0 ? 0 : count[0].count }; }); }, } } export const schema = apongoDirectiveTransformer(makeExecutableSchema({ resolvers, typeDefs: mergeTypes([apongoDirectiveTypeDefs, types]), })); export const apolloServer = () => { const server = new ApolloServer({ schema }); return server; };