b1f6c1c4 / graphql-advanced-projection Goto Github PK
View Code? Open in Web Editor NEWFully customizable Mongoose/MongoDB projection generator.
Home Page: https://www.npmjs.com/package/graphql-advanced-projection
License: MIT License
Fully customizable Mongoose/MongoDB projection generator.
Home Page: https://www.npmjs.com/package/graphql-advanced-projection
License: MIT License
To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:
.travis.yml
If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.
Greenkeeper has checked the engines
key in any package.json
file, the .nvmrc
file, and the .travis.yml
file, if present.
engines
was only updated if it defined a single version, not a range..nvmrc
was updated to Node.js 10.travis.yml
was only changed if there was a root-level node_js
that didn’t already include Node.js 10, such as node
or lts/*
. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.For many simpler .travis.yml
configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖
There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot 🌴
Hi,
I've seen in https://itnext.io/graphql-mongoose-a-design-first-approach-d97b7f0c869 how you handle nested, and ref relations.
Actually your way has some problems:
Storing an array of children in a parent is quite an anti pattern:
parent.children
.Populate directly in nested resolvers:
Solution: (yeah because, it's a proposal, I'm not here just to complain 😛)
For the array of children, just put the parentId in child. No more growing array, no more need to populate. And in mongoose, you can define virtual with ref, and it will be exactly the same. See http://mongoosejs.com/docs/populate.html#populate-virtuals.
But this one is for information and have no link with this package.
For the nested resolvers: we have a way to do it muuuch better in my opinion.
Indeed, we can directly populate all the nested and subnested items directly in the first resolver, by writing the populate option with the help of projections !
I've made a bunch of functions to convert projections to a populate config object, and so I can query directly all the demanded item with:
async campaigns(root, args, ctx, info) {
const projections = project(info);
const population = populate(projections);
return Campaign.find({}, projections).populate(population);
},
And with that it will make the minimum number of queries to fetch all the needed documents. Example:
Query:
{
campaigns {
id
title
questions {
id
message
answers {
id
value
}
}
}
}
Mongoose requests done:
campaigns.find({}, { fields: { id: 1, title: 1, 'questions.id': 1, 'questions.message': 1, 'questions.answers.id': 1, 'questions.answers.value': 1, questions: 1 } })
questions.find({ campaignId: { '$in': [ ObjectId("5b59b5c6a30e7b2b8d1ea74f"), ObjectId("5b59b719ad4dd22bbd62750b"), ObjectId("5b59b719ad4dd22bbdv2750b"), [length]: 3 ] } }, { fields: { id: 1, message: 1, answers: 1, campaignId: 1 } })
answers.find({ questionId: { '$in': [ ObjectId("5b5a439a935a0d32bc688f15"), ObjectId("5b5a439a935a0d32bc588f15", ObjectId("5b5a439a935a0d32bc698f15", [length]: 3 ] } }, { fields: { id: 1, value: 1, questionId: 1 } })
Here we have 3 levels asked, so 3 queries in any case.
With nested resolvers, we would have for this concrete case:
10 Campaigns: 1 query.
20 Questions by Campaign: 10 * 1 queries.
3 Answers by Questions: 10 * 20 * 1 queries.
About 200 queries, for only 3 levels. And it will grow with each document and each level added.
Are you interested by a PR with theses functions, and then write some documentation/update the article?
Hallo,
it's a bit difficult to explain...I have a MongoDB collection called "tracking-infos" and a GQL query that returns them for pagination:
type Query {
trackingInfos(query: TrackingInfoQuery!): PaginatedTrackingInfos!
}
type PaginatedTrackingInfos { <= This is "artificial"
data: [TrackingInfo!]!
total: Int!
}
type TrackingInfo { <= This is stored in MongoDB
_id: String!
shippingNumber: String!
symbol: String!
....
}
The query on the web client looks like this:
query GetTrackingInfosForOverview($query: TrackingInfoQuery!) {
trackingInfos(query : $query) {
data {
shippingNumber
// Some other, but not all so that we need a working projection to prevent querying unnecessary stuff
}
total
}
}
My resolver for the trackingInfos-Query looks like this:
const { project, resolvers } = gqlProjection({
TrackingInfo: {
proj: {
"shippingNumber": 1,
"symbol": 1,
...
}
}
};
....
async trackingInfos(obj, args, context, info) {
const proj = project(info);
const total= await this.trackingInfoModel.getTrackingInfosCount(args.query, proj);
const data= await this.trackingInfoModel.findTrackingInfos(args.query, proj);
return {
total,
data
};
}
This won't work though, because the AST in info is "based" on the PaginatedTrackingInfos-type and not on TrackingInfo. I am scratching my head, but can't find a solution how to fix this :-(
Could you tell me if this is possible at all and give me a hint how to do it?
Thanks
Hello, thank you very much for the work so far, it's really appreciated. However - the documentation can be more explicit :( maybe I can contribute in the near future.
The issue I am experiencing is with the following virtual field:
This virtual field is an array (notice option justOne: false)
I am selecting in graphql the virtual field as following:
Now please notice the comparison of a working and non working example. The different is adding the projection.
What happens is:
Result
Hi, I'm using your package and trying to do something cool for mutations too.
Could you provide some examples?
Here an example of nested items, where I want just to add a child and return the parent.
For now, I have:
async addQuestion(root, { campaignId, question }, ctx, info) {
const campaign = await Campaign.findById(campaignId);
const lenght = campaign.questions.push(question);
return campaign.save();
}
mutation($campaignId: ID, $question: QuestionInput) {
addQuestion(question: $question, campaignId: $campaignId) {
id
title
}
}
which is pretty bad because I can't really select any field of the object, and load everything.
If I use the projection in the findById
, questions
is undefined.
And if I have a lot of questions in campaign, they will all be loaded (with their own children) for nothing.
Do you have any ideas/tips ?
Thanks!
Could you pls write a d.ts file for this module so that it can support for typescript?
I have tried to write one by myself but some variables' types are confusing.
With
query LastCampaign {
lastCampaign {
id
title
questions {
id
message
}
}
}
it works,
With
query LastCampaign {
lastCampaign {
id
title
questions {
id
message
__typename
}
}
}
It doesn't.
We should be able to add __typename with any consequences in queries (and apollo does that: https://stackoverflow.com/questions/45509228/why-do-graphql-fragments-need-typename-in-queries).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.