graphql-to-mongodb
graphql-to-mongodb copied to clipboard
Handling ObjectId in filter
Say I want to get a specific person record and filter by _id
person (
filter: {
_id: { EQ: "5e1e2d653a32a05f51f621c1" }
}
) {
name {
lastName
}
age
}
Currently that will generate a filter like so
{ _id: { '$eq': '5e1e2d653a32a05f51f621c1' }
Can you detect when "_id" is used and make it essentially do this instead?
{ _id: { '$eq': new ObjectId('5e1e2d653a32a05f51f621c1') }
Sorry for the overdue response.
That sounds like a feature worth adding to the package. I'm not sure when I'll get around to it, but in the meantime you can:
- Add a PR
- Since querying by
_id
about makes every other filter obsolete you can create a field like:id: { type: PersonType, args: { _id: { type: new GraphQLNonNull(GraphQLString) } }, resolve: async (obj, args, { db }: { db: Db }, info) => { const projection = getMongoDbProjection(info, PersonType); return await db.collection('people').find({ _id: new ObjectId(args._id) }, { projection }).toArray(); } }
As long as your scalar type is ObjectId and not string it works just fine. same with date BTW.
or make your own... ObjectId
import { GraphQLScalarType, Kind } from "graphql";
import { ObjectId } from "mongodb";
export const ObjectIdScalar = new GraphQLScalarType({
name: "ObjectId",
description: "Mongo object id scalar type",
parseValue(value: string) {
return new ObjectId(value); // value from the client input variables
},
serialize(value: ObjectId) {
return value.toHexString(); // value sent to the client
},
parseLiteral(ast) {
if (ast.kind === Kind.STRING) {
return new ObjectId(ast.value); // value from the client query
}
return null;
},
});
and date...
import { GraphQLScalarType, Kind } from "graphql";
export const GraphQLISODateTime = new GraphQLScalarType({
name: "DateTime",
description:
"The javascript `Date` as string. Type represents date and time as the ISO Date string.",
parseValue(value: string) {
return new Date(value);
},
serialize(value: Date) {
if (!(value instanceof Date)) {
throw new Error(`Unable to serialize value '${value}' as it's not instance of 'Date'`);
}
return value.toISOString();
},
parseLiteral(ast) {
if (ast.kind === Kind.STRING) {
return new Date(ast.value);
}
return null;
},
});
As long as your scalar type is ObjectId and not string it works just fine. same with date BTW.
or make your own... ObjectId
import { GraphQLScalarType, Kind } from "graphql"; import { ObjectId } from "mongodb"; export const ObjectIdScalar = new GraphQLScalarType({ name: "ObjectId", description: "Mongo object id scalar type", parseValue(value: string) { return new ObjectId(value); // value from the client input variables }, serialize(value: ObjectId) { return value.toHexString(); // value sent to the client }, parseLiteral(ast) { if (ast.kind === Kind.STRING) { return new ObjectId(ast.value); // value from the client query } return null; }, });
and date...
import { GraphQLScalarType, Kind } from "graphql"; export const GraphQLISODateTime = new GraphQLScalarType({ name: "DateTime", description: "The javascript `Date` as string. Type represents date and time as the ISO Date string.", parseValue(value: string) { return new Date(value); }, serialize(value: Date) { if (!(value instanceof Date)) { throw new Error(`Unable to serialize value '${value}' as it's not instance of 'Date'`); } return value.toISOString(); }, parseLiteral(ast) { if (ast.kind === Kind.STRING) { return new Date(ast.value); } return null; }, });
I also am trying to learn graphql with this library and encountered the same problem. Yup this helped me
When I try the above custom scalar type code, I receive...
Argument type {name: string, description: string, parseValue(=): , serialize(): , parseLiteral(): ( | null)} is not assignable to parameter type GraphQLScalarTypeConfig<*, *>
I think that's just a warning from my IDE. The code compiles, but at runtime I receive the error... TypeError: graphQLType.getFields is not a function