You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:20:12