mongo 唯一约束索引_关于mongodb:Mongoose唯一索引不起作用!

我试图让MongoDB根据其索引检测重复值。 我认为这在MongoDB中是可能的,但是通过Mongoose包装器,事情似乎被打破了。 所以对于这样的事情:

User = new Schema ({

email: {type: String, index: {unique: true, dropDups: true}}

})

我可以用同一封电子邮件保存2个用户。 真是

在这里也表达了相同的问题:https://github.com/LearnBoost/mongoose/issues/56,但是该线程很旧,导致无处可去。

现在,我正在手动调用数据库以查找用户。 由于对"电子邮件"进行了索引,因此该调用并不昂贵。 但是让它在本地处理仍然会很好。

有人对此有解决方案吗?

坏消息,仍然是mongod v2.4.3,mongoose v3.6.20的问题

唯一性似乎可以在我的一台主机上工作,但是无法在另一台主机上使用完全相同的节点/猫鼬代码来强制执行唯一性。 运行正常的主机运行单个mongod 3.4.10,而不运行单个mongod 3.4.10-运行具有mongod 3.2.17的副本集。在这两个主机上,Im从头开始创建一个集合,因此现有的复制不是问题。 我已经尝试过此页面上的大多数解决方案,而有效的解决方案是@Isaac Pak的mongoose-unique-validator。

糟糕!您只需要重新启动mongo。

我遇到同样的问题,但是我找不到如何在OSX上重新启动mongo的方法。当我终止该进程时,它将再次自动产生,并且唯一索引仍然不起作用...有什么想法吗?

您是什么意思"哎呀,您只需要重启mongo" ?!您是在说不关闭数据库就不可能添加索引吗?

这不是真的。您无需重新启动mongo即可添加索引。

为独特的事情..我不得不重启mongo ..并且它起作用..谢谢!

我尝试重新启动。也重新索引。不得不删除数据库来解决这个问题。猜测问题是添加索引之前已经存在重复项,因此在生产数据库中,我需要删除重复项然后重新启动?

我认为这是最短的答案。

@isimmons删除收藏集对我有用。感谢您的评论。

我重新启动了mongod并退出了所有客户端,然后重新启动了mongod,但仍然出现相同的行为。我正在使用mongo v3.4.17和mongoose 5.2.15。我收到有关collection.ensureIndex的弃用警告,但它告诉我改用createIndexes,所以我测试了Model.createIndexes()...

Oops! You just have to restart mongo.

并使用以下方法重新编制索引:

mongo

> db..reIndex()

在测试中,由于我没有重要数据,因此您也可以执行以下操作:

mongo

> db.dropDatabase()

db.dropDatabase()擦除数据库!

我遇到了同样的问题:在已经将用户添加到数据库之后,我将email字段的唯一约束添加到了我们的UserSchema中,并且仍然能够使用重复电子邮件保存用户。我通过执行以下操作解决了这个问题:

1)从用户集合中删除所有文档。

2)在mongo shell中,执行命令:

db.users.createIndex({email: 1}, {unique: true})

关于步骤1,请注意,来自Mongo的文档:

MongoDB cannot create a unique index on the specified index field(s) if the collection already contains data that would violate the unique constraint for the index.

https://docs.mongodb.com/manual/core/index-unique/

这对我来说很完美

这对我有用

如果您在Mongo中保留了一些重复项,也会发生此行为。当您的应用程序启动时,Mongoose将尝试在Mongo中创建它们。

为了防止这种情况,您可以通过以下方式处理此错误:

yourModel.on('index', function(err) {

if (err?) {

console.error err

}

);

好的,我可以通过在字段上添加索引并设置unique属性来从mongoshell中解决此问题:

db..ensureIndex({fieldName: 1}, {unique: true});

Shell应该以这种方式做出响应:

{

"createdCollectionAutomatically" : false,

"numIndexesBefore" : 1,

"numIndexesAfter" : 2,

"ok" : 1

}

现在从mongoshell快速测试:

var doc = {fieldName: 'abc'};

db..insert(doc)

应该给:

WriteResult({" nInserted":1})

但是,当再次重复时:

db..insert(doc)

会给:

WriteResult({

"nInserted" : 0,

"writeError" : {

"code" : 11000,

"errmsg" :"insertDocument :: caused by :: 11000 E11000 duplicate key error index: fuelConsumption.users.$email_1  dup key: { : "martyna@martycud.com" }"

}

})

这还告诉您已经存在哪些重复条目。

从应用程序级别强制执行唯一索引时,猫鼬有点松散;因此,最好是使用mongo cli从数据库本身强制您的唯一索引,或者通过在UserSchema之后编写以下代码行来明确告诉mongoose您对unique索引很认真:

UserSchema.index({ username: 1, email: 1 }, { unique: true});

这将在UserSchema的username和email字段上强制使用唯一索引。干杯。

晚了一点,但是ORM有什么好处,那就是"强制执行唯一索引时有点松动"

轻浮的评论毫无用处,这有什么用。该解决方案是可靠的并且已经可以生产。

我做了这样的事情:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const FooSchema = new Schema({

name: { type: String, required: true, index: true, unique: true }

});

const Foo = mongoose.model('Foo', FooSchema);

Foo.createIndexes();

module.exports = Foo

我添加了Foo.createIndexes()行b.c.运行代码时,我收到以下弃用警告:

(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.

我不确定Foo.createIndexes()是否异步,但是AFAIK似乎工作正常

该问题的唯一答案是解决问题而不是围绕问题解决。

根据文档:https://docs.mongodb.com/v2.6/tutorial/modify-an-index/

To modify an existing index, you need to drop and recreate the index.

不要重启MONGO!

1-删除集合

db.users.drop()

2-重新索引表格

db.users.ensureIndex({email: 1, type: 1}, {unique: true})

猫鼬唯一验证器

如何使用此插件:

1)npm install-保存猫鼬唯一验证器

2)在您的架构中,请遵循以下指南:

// declare this at the top

var mongoose = require('mongoose');

var uniqueValidator = require('mongoose-unique-validator');

// exampleSchema = mongoose.Schema({}) etc...

exampleSchema.plugin(uniqueValidator);

// module.exports = mongoose.model(...) etc....

3)猫鼬的方法

使用findOneAndUpdate之类的方法时,您需要传递此配置对象:

{ runValidators: true, context: 'query' }

ie. User.findOneAndUpdate(

{ email: 'old-email@example.com' },

{ email: 'new-email@example.com' },

{ runValidators: true, context: 'query' },

function(err) {

// ...

}

4)其他选项

不区分大小写

在模式中使用uniqueCaseInsensitive选项

ie. email: { type: String, index: true, unique: true, required: true, uniqueCaseInsensitive: true }

自定义错误消息

ie. exampleSchema.plugin(uniqueValidator, { message: 'Error, expected {PATH} to be unique.' });

现在,您可以向架构中添加/删除唯一属性,而不必担心重启mongo,删除数据库或创建索引。

注意事项(来自文档):

因为我们依靠异步操作来验证数据库中是否存在文档,所以有可能同时执行两个查询,两个查询都返回0,然后都插入到MongoDB中。

除了自动锁定集合或强制单个连接之外,没有真正的解决方案。

对于我们大多数用户来说,这不是问题,但是这是一个边缘情况。

您也可以通过删除索引来解决此问题。

假设您要从集合users和字段username中删除唯一索引,请输入以下内容:

db.users.dropIndex('username_1');

最新答案:根本不需要重新启动mongodb,

如果colleciton已经具有相同的名称索引,猫鼬将不会重新创建

再次创建索引,因此,首先删除大学的现有索引,

现在,当您运行猫鼬时,它将创建新索引,

以上过程解决了我的问题。

检查模式中的autoIndex是否为true,使用mongoose.connect选项时可能将其设置为false(默认为true)

如果表/集合为空,则为该字段创建唯一索引:

db..createIndex({'field':1}, {unique: true})

如果表/集合不为空,则删除集合并创建索引:

db..drop()

db..createIndex({'field':1}, {unique: true})

现在重新启动mongoDB。

遇到此问题时,我尝试删除数据库,并多次重新启动服务器(nodemon),但所有技巧都没有用。通过Robo 3T,我发现以下解决方法:

在Robo 3T中,双击数据库以打开集合

打开收藏集以显示有问题的收藏集。首先,请确保您的收藏集为空

用鼠标右键单击索引文件夹。默认情况下,您将看到_id_作为默认值。现在,选择添加索引

选择一个名称,例如在电子邮件字段中说email

提供密钥作为JSON。例如

{

"email": 1

}

单击唯一复选框

这将确保在MongoDB中不会保存重复的电子邮件。

如果在这样的连接方法中使用选项autoIndex: false:

mongoose.connect(CONNECTION_STRING, { autoIndex: false });

尝试删除它。如果这样不起作用,请尝试按照此线程中的建议重新启动mongodb。

您可以将架构定义为

User = new Schema ({

email: {

type: String,

unique: true

}

})

但是,当已经有一个文档,然后又更改了用户的架构时,这可能无法正常工作。如果您不想删除该用户集合,则可以在电子邮件上为其创建索引。使用此命令可以在电子邮件上创建索引。

db.User.createIndex({email:1},{unique: true})

或者,您可以删除集合并再次添加用户。

对于删除集合,您可以输入以下内容:

db.User.drop()

我有一段时间遇到相同的问题,并进行了大量搜索,而对我来说,解决方案是createIndexes()函数。

希望对您有所帮助。

因此代码将是这样。

User = new Schema ({

email: {type: String, unique: true}

});

User.createIndexes();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值