在使用Mongoose创建对象之前检查唯一字段

时间:2017-10-31 19:50:50

标签: javascript mongoose promise graphql es6-promise

我正在构建一个GraphQL服务器,我需要在将数据提交到数据库(MongoDB和Mongoose)之前进行某种验证。

其中一项检查与唯一字段有关。因此,模型可能有一个或多个唯一字段,我需要能够在保存到数据库之前检查它。

所以,我已经构建了一些辅助函数来完成它,代码如下:

帮助代码:

import mongoose from "mongoose";

const isFieldUnique = (modelName, fieldName, fieldValue) => {

    let model = mongoose.model(modelName);
    let query = {};
    query[fieldName] = fieldValue;
    return model.findOne(query).exec();
};

const executeUniquePromises = (uniques, modelName, data) => {

    let promises = [];
    uniques.map(name => {

        let value = data[name];
        if (!value)
            throw new Error("Cannot test uniqueness for a null field.");

        promises.push(
            isFieldUnique(modelName, name, value)
            .then(value => {
                if (value) {
                    let error = name + ' is not unique';
                    console.log(error);
                    return error;
                }

                console.log(name + ' is unique');
                return null;
            })
            .catch(error => {
                throw new Error(error);
            })
        )
    });

    return Promise.all(promises);
};

export const checkUniqueness = (uniques, modelName, data) => {

    return new Promise((resolve, reject) => {

        executeUniquePromises(uniques, modelName, data).then(result => {

            let errors = [];

            // Check for errors
            result.map((error) =>  {
                if (error)
                    errors.push(error);
            });

            if (errors.length > 0)
                return reject(errors);
            else
                resolve();
        });
    });
}

Mongoose静态创建功能:

import * as helper from './helper';

schema.statics.create = function (data) {

    let uniques = ['name', 'email'];
    helper.checkUniqueness(uniques,'Company', data)
    .then(result => {
            let user = new this(data);
            return company.save();
    })
    .catch(error => {
            throw new Error(error);
    });
}

GraphQL代码:

const createUser = {
    type: UserType,
    description: "Create a user",
    args: {
        data: {
            name: "user",
            type: new GraphQLNonNull(UserInputType)
        }
    },
    resolve(root, args) {
        return UserModel.create(args.data);
    }
};

帮助代码变得混乱,我没有使用我对其他承诺的promises使用是正确的方法。

请记住,我可能需要检查几个字段的唯一性,这就是为什么我创建了promise数组。

一个问题是,当我插入没有唯一匹配的数据时,我的GraphQL服务器中没有返回。

我想找到一种更好的方法,并发现为什么我没有收回保存的对象。

1 个答案:

答案 0 :(得分:2)

MongoDB已经开箱即可处理unique。在Mongoose架构中将字段设置为unique: true。您可以使用mongoose-beautiful-unique生成类似于验证错误消息的错误消息。最后,如果无法让unique: true工作,请阅读this