node.js - Mongoose 中的自增字段

标签 node.js mongodb mongoose graphql graphql-js

我正在尝试使用 Mongoose 创建一个 API,并且我有一个模型,我想在其中自动递增 postID 的值。 我有帖子架构

const PostSchema = new Schema({
    title: {
        type: String,
        required: true
    },
    postID: {
        type: Number,
        unique: true,
        required: true
    },
    body: {
        type: String,
        required: true
    },
    author: {
        type: Schema.Types.ObjectId,
        ref: 'Author',
        required: true
    },
    dateCreated: {
      type: Date,
      required: true
    },
    lastModified: {
        type: Date,
        required: false
    },
    modifiedBy: {
        type: Schema.Types.ObjectId,
        ref: 'Author',
        required: false
    },
    picture: {
        type: mongoose.SchemaTypes.Url,
        required: false
    }
}, {collection: 'Post'});

我已经创建了一个预保存 Hook

export const PostModel =  mongoose.model('Post', PostSchema);

PostSchema.pre('save', true, async function (next) {
    const post = this;
    post._id = new ObjectID();
    post.dateCreated = new Date();
    try {
        const lastPost = await PostModel.find({postID: {$exists: true}}).sort({id: -1}).limit(1);
        post.postID = lastPost.postID + 1;
    } catch (e){
        console.log('could not take the last post')
    }
    if(post && post.hasOwnProperty('body') && !post.body.isModified){
        return next();
    }
    if(post && post.hasOwnProperty('body') && post.body.isModified){
        post.lastModified = new Date();
        return next();
    }
});

处理添加创建日期和自动递增 postID。然而,每当我向 API 发送突变以创建新帖子时,我都会收到一个错误: 后验证失败:dateCreated:路径 dateCreated 是必需的。,id:路径 id 是必需的。 这意味着预保存 Hook 中处理的任何工作都没有完成。每当我向解析器添加一些随机值时,突变都会成功完成。知道为什么预保存不起作用吗?

这是我的解析器

module.exports.addPost = async(_,args, req) => {
    const post = new PostModel({
        title: args.post.title,
        body: args.post.body,
        author: new ObjectID(args.post.author),
        picture: args.post.picture
    });
    try {
        return await post.save();
    } catch (e) {
        console.log('Could not save the post');
        console.log(e);
    }
};

这里是突变

curl 'http://localhost:3001/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: http://localhost:3001' --data-binary '{"query":"mutation($post: PostInput){\n  addPost(post: $post){\n    title\n    body\n    author\n  }\n}","variables":{"post":{"title":"newTitle","body":"Lorem ipsum","author":"5e07e6c07156cb000092ab45","picture":"http://www.example.com"}}}' --compressed

最佳答案

上面的代码片段不起作用。根据 Mongoose 的文档,编译模型后调用 pre 或 post hooks 不起作用。所以你应该移动

export const PostModel =  mongoose.model('Post', PostSchema);

在前钩下方。另外,由于 PostModel 尚未定义,并且您想要获取插入数据库的对象的最后一个 id,因此您可以将此检查移至解析器。

   let lastPost = await PostModel.find({id: {$exists: true}}).sort({id: -1}).limit(1); 
    // This always returns an array, either empty or with data
    if(Array.isArray(lastPost) && lastPost.length > 0){
        lastPost = lastPost[0]
    }
    const post = new PostModel({
        ...
        id: lastPost['id'] + 1
        ...
    });
    if(Array.isArray(lastPost) && lastPost.length === 0) {
        post.id = 0;
    // If this lastPost is an empty array and you try to access the id property
    // you will get an error that NaN to Int conversion failed
    }

希望这有帮助

关于node.js - Mongoose 中的自增字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59516237/

相关文章:

javascript - express 返回帖子信息由另一个功能处理

node.js - 无法在 Typescript 中使用 Bluebird promisifyAll Redis api

node.js - 如何过滤数组元素

Mongodb - 从查找中获取对象而不是数组

javascript - 尝试在 Mongoose 中使用 .find() 时出错

node.js - 如何在 CentOS 服务器上安装 Parse Server?

node.js - MongoDB:处理自动递增的模型 id 而不是 Mongo 的 native ObjectID

java - log4j + log4mongo - 配置不同级别的多个appender

mongodb - 在 MongoDB 中,唯一索引对分片键的实际限制是什么?

node.js - 为什么 mongoosastic 填充/ Elasticsearch 没有填充我的引用之一?我得到一个空对象