《nodejs开发指南》的问题-E11000 duplicats key error index: microblog.posts.$user_1 dup key: { : null}
发布于 11 年前 作者 iq9891 5950 次浏览 最后一次编辑是 8 年前

再做博客系统的时候,不知道为什么老是报错——MongoError: E11000 duplicats key error index: microblog.posts.$user_1 dup key: { : null}

相关代码如下,请大神帮忙看看吧

post.js代码 var mongodb = require(’./db’);

function Post (username, post, time) { this.user = username; this.post = post; if(time){ this.time = time; }else{ this.time = new Date(); } }

module.exports = Post;

Post.prototype.save = function save(callback) { //存入mongoDB的文档 var post = { user : this.user, to : “to”, post : this.post, time : this.time };

mongodb.open(function(err, db){ if(err){ return callback(err); }

//读取posts集合 db.collection(‘posts’, function(err, collection){ if(err){ mongodb.close(); return callback(err); }

collection.ensureIndex(‘user’,{ unique:true },{w: 0}); collection.insert(post,{safe: true}, function(err, posts){ mongodb.close(); console.log(err) console.log(posts +“我”) callback(err, posts); }); //为user属性添加索引

}); }); };

Post.get = function get(username, callback){ mongodb.open(function(err, db){ if(err){ return callback(err); } //读取posts集合 db.collection(‘posts’, function(err, collection){ if(err){ mongodb.close(); return callback(err); }

//查找user属性为username的文档,如果username是null则匹配全部 var query = {}; if(username){ query.user = username; } collection.find(query).sort({time: -1}).toArray(function(err, docs){ mongodb.close(); if(err){ callback(err, null); } //封装posts为Post对象 var posts = []; docs.forEach(function(doc, index){ var post = new Post(doc.user, doc.post, doc.time); posts.push(post); }); callback(null, posts); }) }); }); };

index.js代码

/*

  • GET home page. */; var crypto = require(‘crypto’), User = require(’…/modules/user.js’), Post = require(’…/modules/Post.js’);

module.exports = function(app){ app.get(’/’, function(req, res){ Post.get(null, function(err, posts){ if(err){ posts = []; } res.render(‘index’, { title: ‘首页’, posts: posts ,user:req.session.user, success:req.flash(‘success’).toString(), error:req.flash(‘error’).toString() }); }); });

app.get(’/reg’, checkNotLogin); app.get(’/reg’, function(req, res){ res.render(‘reg’, { title : ‘用户注册’ ,user:req.session.user, success:req.flash(‘success’).toString(), error:req.flash(‘error’).toString() }); });

app.post(’/reg’, checkNotLogin); app.post(’/reg’, function(req, res){

//检验用户两次输入的口令是否一致 if (req.body[‘password-repeat’] != req.body[‘password’]) { req.flash(‘error’, “密码不一致”); return res.redirect(’/reg’); }

//生成口令的散列值 var md5 = crypto.createHash(‘md5’); var password = md5.update(req.body.password).digest(‘base64’);

var newUser = new User({ name : req.body.username, password : password });

//检查用户名是否存在 User.get(newUser.name, function(err, user){ if(user){ err = ‘用户存在’; } if(err){ req.flash(‘error’, err); return res.redirect(’/reg’); } //如果不存在则新增用户 newUser.save(function(err){

 if(err){
  req.flash('error', err.stack);
  return res.redirect('/reg');
 }
 req.session.user = newUser;
 req.flash('success', '注册成功');
 res.redirect('/');
})

}) });

app.get(’/login’, checkNotLogin); app.get(’/login’, function(req, res){ res.render(‘login’, { title: ‘用户登录’ ,user:req.session.user, success:req.flash(‘success’).toString(), error:req.flash(‘error’).toString() }); });

app.post(’/login’, checkNotLogin); app.post(’/login’, function(req, res){ //生成口令的散列值 var md5 = crypto.createHash(‘md5’); var password = md5.update(req.body.password).digest(‘base64’);

User.get(req.body.username, function(err, user){ if(!user){ req.flash(‘error’, “用户不存在”); return res.redirect(’/login’); } if(user.password != password){ req.flash(‘error’, ‘用户口令错误’); return res.redirect(’/login’); } req.session.user = user; req.flash(‘success’, ‘登入成功’); res.redirect(’/’); }); });

app.get(’/logout’, checkLogin); app.get(’/logout’, function(req,res){ req.session.user = null; req.flash(‘success’, ‘登出成功’); res.redirect(’/’); }); /* app.get(’/post’, checkNotLogin); app.post(’/post’, function(req, res){ res.render(‘user’, { title: ‘用户发表’ ,user:req.session.user, success:req.flash(‘success’).toString(), error:req.flash(‘error’).toString() }); }); */ app.post(’/post’, checkLogin); app.post(’/post’, function(req, res){ var currentUser = req.session.user; var post = new Post(currentUser.name, req.body.post); post.save(function(err){ if(err){ req.flash(‘error’, err); console.log(“我2” +"+" +post.user +"-" + post.user +"-"+post.post) return res.redirect(’/’); } console.log(“我”) req.flash(‘success’, ‘发表成功’); res.redirect(’/u/’ + currectUser.name); }); });

app.get(’/u/:user’, function(req, res){ User.get(req.params.user, function(err, user){ if(!user){ req.flash(‘error’, ‘用户不存在’); return res.redirect(’/’); } Post.get(user.name, function(err, posts){ if(err){ req.flash(‘error’, err); return res.redirect(’/’); } res.render(‘user’, { title: user.name, posts: posts }); }); }); }); };

function checkLogin (req, res, next){ if(!req.session.user){ req.flash(‘error’, ‘未登录’); return res.redirect(’/login’); } next(); }

function checkNotLogin (req, res, next){ if(req.session.user){ req.flash(‘error’, ‘已登录’); return res.redirect(’/’); } next(); }

4 回复

注意你建立了一个唯一索引: collection.ensureIndex(‘user’,{ unique:true },{w: 0}); 出现这个问题应该是你的posts中出现重复的user了。

在注册的时候,也有一个这样的索引。也是用user做的索引。在post中也是用user做的。就重复了,有没有解决的方法呢?

user.js代码

var mongodb = require(’./db’);

function User (user) { this.name = user.name; this.password = user.password; }

module.exports = User;

User.prototype.save = function save(callback) { var user = { name: this.name, password: this.password, };

mongodb.open(function(err, db){ if(err){ return callback(err); }

db.collection(‘users’, function(err, collection){ if(err){ mongodb.close(); return callback(err); } /* collection.remove(user,function(err,result){ console.log(result); }); */ collection.ensureIndex(‘name’,{ unique:true },{w: 0}); collection.insert(user,{safe: true}, function(err, user){ mongodb.close(); console.log(err) console.log(user) callback(err, user); }); }); }); };

User.get = function get(username, callback){ mongodb.open(function(err, db){ if(err){ return callback(err); }

db.collection(‘users’, function(err, collection){ if(err){ mongodb.close(); return callback(err); }

collection.findOne({ name: username },function(err, doc){ mongodb.close(); if(doc){ var user = new User(doc); callback(err, user); } else { callback(err, null); } }); }); }); };

你这两个地方索引是不一样的,如果你想不加入重复,可以添加如下选项来删除重复的:

collection.ensureIndex('user', {unique:true,dropDups:true}, {w: 0});

但是这样无法保证会删除哪一条。最好的办法其实你可以在save之前做个唯一验证,防止加入重复。

当然你得考虑这个唯一是否是必要的(根据业务需求来),如果不必要,就不要加unique:true

回到顶部