在使用 Mongoose 创建对象之前检查唯一字段
Posted
技术标签:
【中文标题】在使用 Mongoose 创建对象之前检查唯一字段【英文标题】:Check for unique fields before creating object using Mongoose 【发布时间】:2018-04-13 02:24:38 【问题描述】:我正在构建一个 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);
;
帮助程序代码看起来很混乱,我没有将我的 Promise 与其他 Promise 一起使用是正确的做法。
请记住,我可能需要检查几个字段的唯一性,这就是我创建 promise 数组的原因。
一个问题是,当我在没有唯一匹配项的地方插入数据时,我的 GraphQL 服务器没有返回。
我想找到一种更好的方法,并找出为什么我没有取回保存的对象。
【问题讨论】:
【参考方案1】:MongoDB 已经开箱即用地处理unique。在 Mongoose 模式中将该字段设置为 unique: true
。您可以使用mongoose-beautiful-unique 使错误消息类似于验证错误消息。最后,当您无法让unique: true
工作时,请阅读this。
【讨论】:
我知道,但这对我的 GraphQL 服务器没有用,因为错误消息不是应用程序标准。 您只需几行就可以得到与普通验证错误完全一样的消息。唯一的缺点是在发送到数据库之前运行普通验证,而唯一约束由数据库本身检查。因此,普通验证消息永远不会与唯一验证消息同时显示。以上是关于在使用 Mongoose 创建对象之前检查唯一字段的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB/Mongoose - 仅当某个字段是唯一的时才将对象添加到对象数组中