MEAN栈项目MongoDB查询Date返回数字字符串问题求助
问题原因
这问题本质是GraphQL对Mongoose Date类型的默认序列化处理。Mongoose的Date对象转JSON时,默认会序列化为时间戳数字;而你的GraphQL Schema里,userbooking类型未明确指定日期字段的类型,GraphQL会默认按Mongoose返回的原始时间戳处理,最终转成字符串输出。
另外你之前的Resolver代码没加await,userbooking.find({})返回的是Mongoose Query对象而非实际数据,这也可能加剧序列化的异常表现。
解决方法
这里提供三种实用的处理方式:
1. 修改Mongoose模型的JSON序列化规则
直接在模型里配置,让Date对象转JSON时输出ISO格式字符串(和MongoDB里显示的格式一致):
const userbookingSchema = new mongoose.Schema({ booking_date:{ type: Date, default: Date.now, required:[true,"Please enter booking date"], }, booking_start:{ type: Date, required:[true,"Please enter booking start"], }, booking_end:{ type: Date, required:[true,"Please enter booking end"] } }, { // 添加JSON序列化配置 toJSON: { transform(doc, ret) { // 把所有日期字段转为ISO字符串 ret.booking_date = ret.booking_date.toISOString(); ret.booking_start = ret.booking_start.toISOString(); ret.booking_end = ret.booking_end.toISOString(); return ret; } } });
2. 自定义GraphQL日期标量类型
如果需要更灵活的日期处理(比如同时支持输入输出ISO字符串和时间戳),可以自定义日期标量:
const { GraphQLScalarType, Kind } = require('graphql'); // 自定义日期标量 const DateScalar = new GraphQLScalarType({ name: 'Date', description: '自定义日期类型,支持ISO字符串与Date对象互转', serialize(value) { // 输出时将Date对象转为ISO字符串 return value instanceof Date ? value.toISOString() : null; }, parseValue(value) { // 输入时将字符串转为Date对象 return new Date(value); }, parseLiteral(ast) { if (ast.kind === Kind.STRING) { return new Date(ast.value); } return null; }, });
然后在GraphQL Schema中注册并使用这个标量:
scalar Date type userbooking { booking_date: Date booking_start: Date! booking_end: Date! # 其他字段... } type Query { getuserbooking:[userbooking] }
最后在Resolver中引入该标量(以Apollo Server为例):
const server = new ApolloServer({ typeDefs, resolvers: { Date: DateScalar, Query: { getuserbooking: async ()=>{ return await userbooking.find({}) } } }, });
3. 在Resolver里手动转换日期字段
如果不想改动模型或自定义标量,也可以直接在Resolver里手动转换:
getuserbooking: async ()=>{ // 必须加await获取实际数据 const userListinglist = await userbooking.find({}); // 遍历转换每个文档的日期字段 return userListinglist.map(item => ({ ...item.toObject(), booking_start: item.booking_start.toISOString(), booking_end: item.booking_end.toISOString(), booking_date: item.booking_date.toISOString() })); }
内容的提问来源于stack exchange,提问作者Echohead
相关产品推荐
相关产品推荐

