【纠错】关于mongoose中的model方法创建collection自动加s的问题
发布于 5 年前 作者 Yuki-Minakami 5093 次浏览 来自 分享

今天看到一篇文章 根据网上别人的分享和mongoose文档… (这文章引用了不少Mongoose学习参考文档——基础篇 ,然而引用的原文里错误连篇,具体的错误已经列在评论区中,需要谨慎判断)

联想到了到了一个问题,首先看下面的代码

	var PersonModel = mongoose.model('Person',PersonSchema)

如果数据库中不存在名为Person的collection,那么执行插入操作后就会创建一个。 然而运行一下会发现,在插入一条记录后,数据库中创建了一个名叫People的collection,很简单,是Person的复数形式。 people.png 但开发者肯定不希望建一个名叫people的collection,难道还得费劲去记名词的复数形式吗?

稍微翻一下文档就能发现model方法的构造函数 图片 22.png 看到了,第三个参数才是数据库中collection的名字,第一个参数只是model的名字,想一下也能明白,collection不是存了很多model吗,那就取复数呗 但这肯定不是我们想要的,因此还是老老实实地写上第三个参数。 下面是我写的另一个例子:

	var mongoose = require('mongoose');	
	mongoose.connect('mongodb://localhost/cnodeTest');
	var db = mongoose.connection;

	db.once('open', function (callback) {

    	console.log("connected");
    	var loginSchema = new mongoose.Schema({
       	 	username:String,
        	password:String
    	});
    	var loginTest = db.model("login",loginSchema);
	
    	var query = new loginTest({username:"lear",password:"lear"})
    	query.save().then(function(doc){
        	console.log(doc);
    	})

	});

运行一下就能发现数据库里多了一个名叫logins的collection 屏幕快照 2017-07-06 下午8.17.14.png

参考了这篇19w阅读量的文章(@nnliang认为这不是个问题,确实这篇文章没提到本文中的问题,这里做个补充) Mongoose学习参考文档——基础篇

这个错误不止存在一篇文章里 使用mongoose过程中遇到的疑惑(已经解决)

13 回复

我真的不想说什么

collection

屏幕快照 2017-07-07 上午11.06.28.png

而你 仔细看我写的东西了吗?

居然还来开帖,你是要在cnode打出你的名气吗?

@nnliang 如果我有错误直接指出就可以了,我改,“打出名气”----脑回路清奇

这不是问题吧,设计上就是这样的吧

注意到了一个问题
var PersonModel = mongoose.model('Person',PersonSchema)
如果数据库中不存在名为Person的collection,那么执行插入操作后就会创建一个。
然而运行一下会发现,在插入一条记录后,数据库中创建了一个名叫People的collection,很简单,是Person的复数形式

你确定是创建了一个叫People的collection?

@imhered 确定建了一个名叫people的collection,可以自行复现一下

mongoose文档里也提到了 ###Mongoose automatically looks for the plural version of your model name

mongoose的期望应该是开发者统一使用Model对象来操作,就像上面引用文章里提到的那样,而不是直接操作数据库里的collection

但默认的复数操作肯定要标重点提出的,不直接看文档肯定会造成疑惑

@Yuki-Minakami 确实是。 mongodb用的不多,创建复数形式这个我知道,我以为都只是单纯的加个s(虽然这个不符合英语的逻辑)😂😂😂😂

@imhered 等回去把初中教的名词复数规则全试一遍 :)

@Yuki-Minakami

自己去看官网,我和之前那位前辈哪里错了?

你这个帖子标题就叫纠错,请问你纠什么错了?

我觉得你还是没能理解,麻烦你先仔细看看我在1楼和2楼写的东西,在说你纠什么错了,

对于问题都没搞清楚就来发纠错帖… 自己脑补一下

再说清楚点: 我写的是 在 ** new Schema ! new Schema ! new Schema ! ** 的时候去手动或者默认主动设置 collectionName new Schema({name: String}, {collection: 'person'}) 像这样,而不是你所谓的 var PersonModel = mongoose.model('Person',PersonSchema, 'person')

你这样是用Schema创建model的时候再设置collectionName, 而我讲的是在 Schema层次就设置, 这样讲你能明白了吗? 你还能告诉我你在纠什么错吗?

再给你看看事实,用你的代码:

	var mongoose = require('mongoose');	
	mongoose.connect('mongodb://localhost/cnodeTest');
	var db = mongoose.connection;

	db.once('open', function (callback) {

    	console.log("connected");
    	var loginSchema = new mongoose.Schema({
       	 	username:String,
        	password:String
    	}, {collection: 'loginnnnnnn'});
    	var loginTest = db.model("login",loginSchema);
	
    	var query = new loginTest({username:"lear",password:"lear"})
    	query.save().then(function(doc){
        	console.log(doc);
    	})
	})

以及你说的 从创建model的时候设置集合名称

	var mongoose = require('mongoose');	
	mongoose.connect('mongodb://localhost/cnodeTest');
	var db = mongoose.connection;

	db.once('open', function (callback) {

    	console.log("connected");
    	var loginSchema = new mongoose.Schema({
       	 	username:String,
        	password:String
    	});
    	var loginTest = db.model("login",loginSchema, 'loginmmmmm');
	
    	var query = new loginTest({username:"lear",password:"lear"})
    	query.save().then(function(doc){
        	console.log(doc);
    	})
	})

最后是创建的集合: 屏幕快照 2017-07-07 下午7.03.45.png

现在你能告诉我 你在纠什么错吗?

如果 你找不到我说的有什么错误,还请你开贴向前辈道歉, 19w的阅读量, 是你想说错就错了么!

@nnliang 首先跟你说声,我的帖子已经改了

好啊,正好周末,就彻底解释清楚,看看这篇19W的帖子还剩多少价值

首先是1.2节

	mongoose.createConnection('localhost','cnodeTest');

试试能不能连上数据库,发现连不上 看看文档描述

	createConnection([uri], [options], [options.config], [options.config.autoIndex], [options.useMongoClient])

其中uri的格式应该是

	[uri] <String> a mongodb:// URI

这个可能是API改动,就不算这个了

2.原文1.5节

	Buffer和ArrayBuffer是Nodejs两种隐藏的对象

请问什么是隐藏的对象? Buffer是个全局对象在Node中出镜率这么高,哪里隐藏了 还有 arrayBuffer是ES2015引入的,别的不说,至少5年前肯定没有ArrayBuffer,我也很好奇这里为啥出现了arrayBuffer。如果你要说这是原文作者发现了ES2015这个新特性,然后加到这篇mongoose文章里,而且就出现了这一次,那就没话说了。 这是个细节,我们还是不算这个

3.原文1.6节 混合类型因为没有特定约束,因此可以任意修改,一旦修改了原型,则必须调用markModified()

    person.anything = {x:[3,4,{y:'change'}]}
    person.markModified('anything');//传入anything,表示该属性类型发生变化
    person.save();

这个样例代码放在这不好,会让人产生误解,因为第二行的代码就算不调markModified也完全ok 4.原文1.7节

var mongoose = require('mongoose');
  var ObjectId = mongoose.Schema.Types.ObjectId;
  var StudentSchema = new Schema({}); //默认会有_id:ObjectId
  var TeacherSchema = new Schema({id:ObjectId});//只有id:ObjectId

这个就很严重了,写一段代码自己验证一番

	var ObjectId = mongoose.Schema.Types.ObjectId;
	var StudentSchema = new mongoose.Schema({}); //默认会有_id:ObjectId
	var TeacherSchema = new mongoose.Schema({id:ObjectId});//只有id:ObjectId

	var sModel = db.model("sModel",StudentSchema);
	var tModel = db.model("tModel",TeacherSchema);
	new sModel().save();
	new tModel().save();

	sModel.find(function(err,doc){
    	console.log(doc);//{ _id: 595f7a70ad422a0e12296969, __v: 0 }
	})

	tModel.find(function(err,doc){
    	console.log(doc);//{ _id: 595f7a70ad422a0e1229696a, __v: 0 } 
	})

就算设置了{id:ObjectId},存进去的结果还是_id

5.然后是2.1节

    var PersonModel = mongoose.model('Person',PersonSchema);
    var krouky = new PersonSchema({name:'krouky',type:'前端工程师'});
    krouky.findSimilarTypes(function(err,persons){
      //persons中就能查询到其他前端工程师
    });

这个就很明显了,第二行的

	new PersonSchema({name:'krouky',type:'前端工程师'});

应该是

	new PersonModel({name:'krouky',type:'前端工程师'});

我就看了两节,剩下的就不仔细一行行分析了,这么多问题摆在这里。

至于你,最大的错误在于说了那句话

	“19W的阅读量,是你想说错就错了么!”

是的,就是错了,Linux都有bug,一篇文章怎么就不能错了?

原文下面的评论也指出了原文作者的错误之处,有的到现在还没改正,没见过你这么跳脚的。

做好一个程序员,首先就不能迷信权威,更何况这个就是个帖子,连权威都算不上


最后,关于标题的【纠错】,就你提出的new Schema()构造函数那个问题,原文确实没错,这里我道歉,本帖已经改正了。 但被这种观念误导的人还不少,认为加s是mongo的特性,因此起了个这样的标题。 而且当我写完上面的答案,发现这个标题反而再合适不过了


这个话题浪费了我很多时间,我不会再回复了,认为我胆小也好怕了也罢,随你

回到顶部