我试图让MongoDB根据索引检测重复值。我认为这在MongoDB中是可行的,但是通过Mongoose包装器似乎已经破坏了。所以对于这样的事情:
User = new Schema ({
email: {type: String, index: {unique: true, dropDups: true}}
})
我可以使用相同的电子邮件保存2个用户。织补。
这里也表达了同样的问题:https://github.com/LearnBoost/mongoose/issues/56,但是那个线程已经老了,无处可去。
现在,我手动调用db来查找用户。由于“电子邮件”已编入索引,因此该电话费用并不昂贵。但让它本地处理仍然是件好事。
有没有人有解决方案?
答案 0 :(得分:76)
糟糕!你只需要重启mongo。
答案 1 :(得分:40)
糟糕!你只需要重启mongo。
并重新索引!
在测试中,我刚做了一个:
mongo <db-name>
> db.dropDatabase()
虽然如果你有重要的数据,你可能只需要:
mongo <db-name>
> db.<collection-name>.reIndex()
答案 2 :(得分:17)
我遇到了同样的问题:在已经将用户添加到数据库之后,我将email
字段的唯一约束添加到我们的UserSchema
,并且仍然可以使用重复电子邮件保存用户。我通过执行以下操作解决了这个问题:
1)从用户集合中删除所有文档。
2)从mongo shell中执行命令:
db.users.createIndex({email: 1}, {unique: true})
关于第1步,请注意来自Mongo的文档:
如果集合中已包含违反索引唯一约束的数据,则MongoDB无法在指定的索引字段上创建唯一索引。
答案 3 :(得分:11)
如果您在Mongo中留下了一些重复项,也会发生此行为。当你的应用程序启动时,Mongoose会尝试在Mongo中创建它们。
为防止这种情况,您可以通过以下方式处理此错误:
yourModel.on('index', function(err) {
if (err?) {
console.error err
}
);
答案 4 :(得分:9)
好的,我可以通过在字段上添加索引并设置唯一属性来从mongoshell解决这个问题:
db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true});
Shell应该以这种方式回应:
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
现在从mongoshell快速测试:
var doc = {fieldName: 'abc'};
db.<collectionName>.insert(doc)
应该给: WriteResult({&#34; nInserted&#34;:1})
但是当再次重复时:
db.<collectionName>.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\" }"
}
})
答案 5 :(得分:5)
从应用程序级别强制执行唯一索引时,Mongoose有点松散;因此,最好使用mongo cli从数据库本身强制执行您的唯一索引,或者通过在UserSchema之后编写以下代码行,明确告诉mongoose您认真对待unique
索引:
UserSchema.index({ username: 1, email: 1 }, { unique: true});
这将在UserSchema中的username
和email
字段上强制执行唯一索引。欢呼声。
答案 6 :(得分:4)
解决问题的步骤:
1。将 unique: true
添加到属性中。
let schema = new mongoose.Schema(
{
name: {
type: String,
unique: true,
required: [true, "name required."],
}
}
);
module.exports = mongoose.model("role", schema);
2。删除集合 - 例如 role
(最后一行)
name
)有重复值3 .重新启动使用 mongoose
库的 Node.js 服务器。
这里的其他一些答案怎么不正确?
autoIndex
选项设置为 true
重启数据库
in sequence
答案 7 :(得分:4)
根据文件:https://docs.mongodb.com/v2.6/tutorial/modify-an-index/
要修改现有索引,您需要删除并重新创建索引。
不要重启MONGO!
1 - 删除集合
db.users.drop()
2 - 重新索引表格
db.users.ensureIndex({email: 1, type: 1}, {unique: true})
答案 8 :(得分:4)
以下任何一种情况下,猫鼬都将无声地添加唯一索引:
在第一种情况下,使用db.collection.getIndexes()
列出索引,并使用db.collection.dropIndex("index_name")
删除旧索引。重新启动Mongoose应用程序时,应正确添加新索引。
在第二种情况下,您需要在重新启动Mongoose应用程序之前删除重复项。
答案 9 :(得分:4)
我已经做了类似的事情:
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()
行。运行代码时,我收到以下弃用警告:
(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
我不确定Foo.createIndexes()
是否异步,但是AFAIK似乎运行正常
答案 10 :(得分:1)
检查架构中的autoIndex是否为true,使用mongoose.connect选项时可能将其设置为false(默认为true)
答案 11 :(得分:1)
最新答案:根本不需要重启mongodb, 如果colleciton已经有相同的名称索引,mongoose将不会重新创建 你的索引再次,所以,首先删除colleciton的现有索引, 而现在,当你运行mongoose时,它会创建新的索引, 上面的过程解决了我的问题。
答案 12 :(得分:1)
如果表/集合为空,则为该字段创建唯一索引:
db.<collection_name>.createIndex({'field':1}, {unique: true})
如果表/集合不为空,则删除集合并创建索引:
db.<collection_name>.drop()
db.<collection_name>.createIndex({'field':1}, {unique: true})
现在重启mongoDB。
答案 13 :(得分:1)
如何使用此插件:
1)npm install --save mongoose-unique-validator
您的架构中的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中。
在自动锁定集合或强制单个连接之外,没有真正的解决方案。
对于我们的大多数用户来说,这不会是一个问题,但需要注意的是边缘情况。
答案 14 :(得分:1)
您也可以通过删除索引来解决此问题;
我们假设您要从集合users
和字段username
中删除唯一索引,请输入以下内容:
db.users.dropIndex('username_1');
答案 15 :(得分:0)
如果您在像这样的连接方法中使用选项autoIndex: false
:
mongoose.connect(CONNECTION_STRING, { autoIndex: false });
尝试将其删除。如果这不起作用,请尝试重新启动mongodb ,如该线程中建议的那样。
答案 16 :(得分:0)
您可以将架构定义为
User = new Schema ({
email: {
type: String,
unique: true
}
})
但是,当已经有一个文档,之后又更改了用户的架构时,可能无法使用。如果您不想删除该用户集合,则可以在电子邮件上为其创建索引。使用此命令,您可以在电子邮件上创建索引。
db.User.createIndex({email:1},{unique: true})
或者您可以删除该集合并再次添加用户。
对于删除集合,您可以输入以下内容:
db.User.drop()
答案 17 :(得分:0)
一段时间以来,我遇到了同样的问题,做了很多搜索,而对我来说,解决方案是createIndexes()
函数。
我希望有帮助。
所以代码将是这样。
User = new Schema ({
email: {type: String, unique: true}
});
User.createIndexes();
答案 18 :(得分:0)
遇到此问题时,我尝试删除数据库,多次重新启动服务器(nodemon),但所有技巧都没有用。我通过Robo 3T找到了以下解决方法:
_id_
作为默认值。现在,选择添加索引email
将密钥提供为JSON。例如
{
"email": 1
}
单击“唯一”复选框
这将确保在MongoDB中不会保存重复的电子邮件。
答案 19 :(得分:0)
请确保您的集合中没有多余的字段,只需在其上放置唯一索引即可。
然后重新启动您的应用程序(猫鼬)。 只是默默地添加索引失败。
答案 20 :(得分:0)
从集合中删除所有文档:
db.users.remove({})
如其他人所述,重新启动对我有用
答案 21 :(得分:0)
如果您的MongoDB是作为服务工作的(简单的找到方法是如果不需要通过终端启动mongod.exe文件就不需要连接数据库),那么在进行更改之后,您可能需要重新启动服务和/或完全删除数据库。
这很奇怪,因为对于某些用户而言,只需删除一个集合即可。其中一些只需要删除数据库。但是这些对我没有用。我删除了数据库,然后重新启动了MongoDB Server服务。
要重新启动服务,请在Windows搜索栏中搜索服务,然后找到MongoDB服务,双击以打开,然后停止并再次启动该服务。
如果其他方法对您不起作用,我相信这会成功。
答案 22 :(得分:0)
在我看来,猫鼬已经过时了。我通过在CMD上运行过时的npm进行了检查。 并更新了“猫鼬”。
请告知这是否对您也有用。
答案 23 :(得分:0)
当您将数据库与应用程序连接时,请添加以下选项:“ audoIndex:true” 例如在我的代码中,我这样做:
#Section to enable node application chart on port 3000
location /chart {
proxy_pass http://localhost:3000/;
}
我还删除了我遇到问题的集合,并重新创建了它以确保它可以工作。 我在以下位置找到了该解决方案:https://dev.to/emmysteven/solved-mongoose-unique-index-not-working-45d5 我还尝试了“重启MongoDB”之类的解决方案,但对我不起作用。
答案 24 :(得分:0)
就我而言,我们需要定义 schema.index 来创建索引。 请查看 Mongoose 文档索引 https://mongoosejs.com/docs/guide.html#indexes,
现在看看下面的代码进行测试:
const schemaUser = new mongoose.Schema(
{
username: {
type: String,
required: true,
index: true,
unique: true,
dropDups: true,
},
hash: String,
created: {
type: Date,
default: Date.now,
},
},
{
autoCreate: true, // auto create collection
autoIndex: true, // auto create indexes
}
)
// define indexes to be create
schemaUser.index({ username: 1 })
const User = mongoose.model('Users', schemaUser)
const newUser = new Users({ username: 'wintzer' })
newUser.save(function (err) {
if (err) console.log(err)
})
答案 25 :(得分:0)
重新启动和使用插件对我来说不起作用,而且使用插件来做一些我们都确信 mongo 可以自己做的事情有点矫枉过正。
所以这里是修复。在您的连接函数中,将此添加到选项对象(第二个参数)
const options = {
autoIndex: true, //this is the code I added that solved it all
}
mongoose.connect(process.env.MONGO_URI, options);