Comments (16)
@marcoreat #53 There was already an issue with the same request. It seems like that you are not the only one who asks for this. :) Please read my comment there and let me know what do you think.
from graffiti-mongoose.
Thanks for the reply. I've read the linked thread, looks good to me.
In this case it's a +1 from me for the orderBy
field and for adding this task to your feature request list.
from graffiti-mongoose.
@marcoreat Okay, added. Are you using Relay? Because you can easily sort on the client side. :)
from graffiti-mongoose.
Thanks!
Yes, I'm using Relay. However AFAIK client side sorting would require fetching all of the documents first and I want to avoid it (I'm dealing with large sets of data).
from graffiti-mongoose.
Good point!
from graffiti-mongoose.
In the meantime, you could easily do it yourself with hooks!
On Wed, 18 Nov 2015 at 13:26 AndrΓ‘s TΓ³th [email protected] wrote:
Good point!
β
Reply to this email directly or view it on GitHub
#59 (comment)
.
from graffiti-mongoose.
@hardchor I've tried it already, but didn't succeed.
I've assumed that I would be able to prepare a hook that injects the sort
option into a mongoose call. But none of the arguments provided by pre
or post
seem to give access to the mongoose's mongodb query. Did I miss something? Is there another way?
from graffiti-mongoose.
Currently it sorts by _id, let me figure out how you can change it with hooks. I need to rewrite the logic in the source code too.
from graffiti-mongoose.
Here's a patch that adds the orderBy
enum type. Feedback? Suggestions?
Feel free to use or modify this implementation as you like.
diff --git a/src/e2e.spec.js b/src/e2e.spec.js
index 1f70233..630ca62 100644
--- a/src/e2e.spec.js
+++ b/src/e2e.spec.js
@@ -268,6 +268,46 @@ describe('e2e', () => {
{node: {name: 'Foo'}}
]);
});
+
+ it('should return results in ascending order', async function Test() {
+ const result = await graphql(schema, `{
+ viewer {
+ users(orderBy: nameAsc) {
+ edges {
+ node {
+ name
+ }
+ }
+ }
+ }
+ }`);
+
+ expect(result.data.viewer.users.edges).to.be.eql([
+ { node: { name: 'Bar' } },
+ { node: { name: 'Foo' } },
+ { node: { name: 'Mother' } }
+ ]);
+ });
+
+ it('should return results in descending order', async function Test() {
+ const result = await graphql(schema, `{
+ viewer {
+ users(orderBy: nameDesc) {
+ edges {
+ node {
+ name
+ }
+ }
+ }
+ }
+ }`);
+
+ expect(result.data.viewer.users.edges).to.be.eql([
+ { node: { name: 'Mother' } },
+ { node: { name: 'Foo' } },
+ { node: { name: 'Bar' } }
+ ]);
+ });
});
describe('mutations', () => {
diff --git a/src/query/query.js b/src/query/query.js
index 1e8b766..0b5f5c5 100644
--- a/src/query/query.js
+++ b/src/query/query.js
@@ -255,7 +255,7 @@ async function connectionFromModel(graffitiModel, args, info) {
return emptyConnection();
}
- const {before, after, first, last, id, ...selector} = args;
+ const {before, after, first, last, id, orderBy, ...selector} = args;
const begin = getId(after);
const end = getId(before);
@@ -277,10 +277,17 @@ async function connectionFromModel(graffitiModel, args, info) {
selector._id.$lt = end;
}
+ let sort = {_id: 1};
+ if (orderBy){
+ sort = {
+ [orderBy.slice(0,-3)]: orderBy.endsWith('Asc') ? 1 : -1
+ };
+ }
+
const result = await getList(Collection, selector, {
skip: offset,
limit: limit,
- sort: {_id: 1}
+ sort
}, info);
const count = await getCount(Collection, selector);
diff --git a/src/type/type.js b/src/type/type.js
index 473e202..cc8c6d9 100644
--- a/src/type/type.js
+++ b/src/type/type.js
@@ -11,6 +11,7 @@ import {
} from 'graphql-relay';
import {
GraphQLString,
+ GraphQLEnumType,
GraphQLFloat,
GraphQLBoolean,
GraphQLID,
@@ -77,14 +78,37 @@ function setTypeFields(type, fields) {
type._typeConfig.fields = () => fields;
}
+const orderByTypes = {};
+function getOrderByType(typeName, fields) {
+ if (!orderByTypes[typeName]){
+ orderByTypes[typeName] = new GraphQLEnumType({
+ name: typeName+"_orderBy",
+ values: reduce(fields, (values, field) => {
+ if (field.type instanceof GraphQLScalarType){
+ values[field.name+"Asc"] = { };
+ values[field.name+"Desc"] = { };
+ }
+ return values;
+ }, {})
+ });
+ }
+ return orderByTypes[typeName];
+}
+
function getArguments(type, args = {}) {
const fields = getTypeFields(type);
+
+ fields.orderBy = {
+ name: 'orderBy',
+ type: getOrderByType(type.name, fields)
+ };
+
return reduce(fields, (args, field) => {
if (field.type instanceof GraphQLNonNull && field.name !== 'id') {
field.type = field.type.ofType;
}
- if (field.type instanceof GraphQLScalarType) {
+ if (field.type instanceof GraphQLScalarType || field.type instanceof GraphQLEnumType) {
args[field.name] = field;
}
from graffiti-mongoose.
@marcoreat Let me try it out ;)
from graffiti-mongoose.
Thank you @marcoreat! I have used your code with a few changes: #61. I prefer to use upper case for enum types.
from graffiti-mongoose.
I like your changes, π .
from graffiti-mongoose.
#61 is merged and released under 4.3.0
.
from graffiti-mongoose.
Thanks! π
from graffiti-mongoose.
please add to readme.
from graffiti-mongoose.
@unirey sure. The orderBy
parameter has a type of GraphQLEnumType
. For each field in your model you need to make two possible value
for this enum. I've named it field.name.toUpperCase() + '_DESC'
for descending order and field.name.toUpperCase() + '_ASC'
for ascending order. In Mongoose when using the sort
option it waits for an object like { name: -1 }
. -1
stands for descending, +1
for ascending order. You need to set the enum values according to this. In you query it will look something like this:
{
viewer {
users(orderBy: NAME_DESC) {
edges {
node {
name
}
}
}
}
}
from graffiti-mongoose.
Related Issues (20)
- Implicit dependency on babel-polyfill HOT 9
- Cannot set currently-valued fields to null in update mutation HOT 2
- How to make a custom field: id? HOT 10
- "TypeError: Cannot read property 'forEach' of undefined" when embedded object field is a reference HOT 6
- Custom query thunk - accepts only InputObject types HOT 3
- Question on customQueries HOT 7
- Example project doesnt work with [email protected] and [email protected] HOT 1
- Async hook support HOT 2
- How to use Express Middleware for Authentication/Authorization. HOT 4
- Get specific field validation error?
- How to mutate nested Schema? HOT 3
- What is different between id and _id HOT 1
- UNMET PEER DEPENDENCY HOT 1
- Maintainer Volunteer Thread HOT 1
- Mongoose ObjectId and GraphQL id is not the same. How to link them? HOT 5
- It is possible to add some description to schema and to be reflected in the docs?
- Does graffiti-mongoose works with react-apollo ? HOT 2
- Custom mutations?
- Custom queries/mutations HOT 1
- setTypeFields bug
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graffiti-mongoose.