E11000 重複キーエラーインデックス MongoDB Mongoose 質問する

E11000 重複キーエラーインデックス MongoDB Mongoose 質問する

以下はモデルuser内の私のスキーマです-user.js

var userSchema = new mongoose.Schema({
    local: {
        name: { type: String },
        email : { type: String, require: true, unique: true },
        password: { type: String, require:true },
    },
    facebook: {
        id           : { type: String },
        token        : { type: String },
        email        : { type: String },
        name         : { type: String }
    }
});

var User = mongoose.model('User',userSchema);

module.exports = User;

これは私がコントローラーで使用している方法です -

var user = require('./../models/user.js');

これは私がデータベースに保存する方法です -

user({'local.email' : req.body.email, 'local.password' : req.body.password}).save(function(err, result){
    if(err)
        res.send(err);
    else {
        console.log(result);
        req.session.user = result;
        res.send({"code":200,"message":"Record inserted successfully"});
    }
});

エラー-

{"name":"MongoError","code":11000,"err":"insertDocument :: caused by :: 11000 E11000 duplicate key error index: mydb.users.$email_1  dup key: { : null }"} 

db コレクションを確認しましたが、重複したエントリは存在しません。何が間違っているのか教えてください。

参考までに、req.body.emailreq.body.passwordを取得しています。

この投稿も確認しましたが、役に立ちませんでしたスタックリンク

完全に削除するとドキュメントが挿入されますが、そうでない場合は、local.email にエントリがあっても「重複」エラーが発生します。

ベストアンサー1

エラー メッセージは、電子メール のレコードがすでに存在することを示していますnull。つまり、電子メール アドレスのないユーザーがすでに存在するということです。

これに関連するドキュメント:

ドキュメントに一意のインデックスのインデックス フィールドに値がない場合、インデックスにはこのドキュメントの null 値が格納されます。一意の制約があるため、MongoDB はインデックス フィールドがないドキュメントを 1 つだけ許可します。インデックス フィールドの値がないドキュメントやインデックス フィールドがないドキュメントが複数ある場合、インデックスの構築は重複キー エラーで失敗します。

一意制約とスパース インデックスを組み合わせて、一意インデックスからこれらの null 値をフィルター処理し、エラーを回避できます。

ユニークなインデックス

スパース インデックスには、インデックス フィールドに null 値が含まれている場合でも、インデックス フィールドを持つドキュメントのエントリのみが含まれます。

つまり、複数のドキュメントがすべてnull値を持つ場合でも、スパース インデックスは問題ありません。

スパースインデックス


コメントより:

エラーには、キーに名前が付けられていると記載されているため、とmydb.users.$email_1の両方にインデックスがあると思われます(前者は古く、現在使用されていません)。Mongoose モデルからフィールドを削除しても、データベースには影響しません。これに該当するかどうか で確認し、 で不要なインデックスを手動で削除してください。users.emailusers.local.emailmydb.users.getIndexes()mydb.users.dropIndex(<name>)

おすすめ記事