Mongoose在创建Model时对Collection的命名策略

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:

 Mongoose是MongoDB的对象模型工具,比如使用下面的代码片段就可以在MongoDB的test数据库中创建一个名字叫“user(关于这个名字是本文的重点)”的集合,集合中保存了一个文档(user1)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var  mongoose = require( "mongoose" );
mongoose.connect( "mongodb://localhost/test" );
var  db = mongoose.connection;
db.on( 'error' , console.error.bind(console,  '... connection error ...' ));
db.once( 'open' function  callback() {
     console.info( "... db open ..." );
});
var  UserSchema = mongoose.Schema({
     name: String,
     age: Number,
     birthday: Date
});
var  User = mongoose.model( "user" , UserSchema);
var  user1 =  new  User({
     name:  "Jack" ,
     age: 23,
     birthday:  new  Date()
});
user1.save( function  (err, user1) {
     if  (err) {
         return  console.error(err);
     }
     console.info(user1);
});



从创建链接到向数据库中写入一个条数据经历了以下步骤:

     1.链接数据库(相当于在使用Hibernate的时候配置数据库),并创建链接;

     2.定义UserSchema(相当于数据库建表) ;

     3.创建User模型(相当于构建对象和数据库表映射);

     4.通过User模块,创建对象

      5.通过save方法持久化对象;


      当然Mongoose是MongoDB的模型工具,所以这里最好不要用表,记录来描述。那么上面描述中的User模型就是MongoDB中的collection,即test数据库中的一个集合,user是指定了集合名。

       运行上述程序之后,回到MongoDB的客户端查看test数据库的集合列表。

wKioL1NhAoTDWPEjAAHNqwjSq4M127.jpg


上图标注的"users"是运行程序创建的Collection,而程序中指定的模型名称为:user, 数据库中的集合名是“users”,这个问题正是本文讲述的重点(Mongoose在创建MongoDB的Collection时的命名策略)。


   使用过MongoDB,应该知道向MongoDB中一个不存在的collection中插入文档,数据库会自动创建一个Collection(集合)。而在使用Monogoose的时候,发现这个问题后,又试了试如下模型名:xx, kitten,发现变化为xx—>xxes, kitten—>kittens。


开始做了个猜想,会不会Collection(集合)意味着要用复数名称,Mongoose对此做了特殊处理,当我把模型名改为:money的时候查看数据库集合发现,集合名称仍然是money。看到这个结果,确定Mongoose在模型名至数据库集合名的命名转换上做了文章。

   模型名设置为money:

wKioL1NhBXTyvWKAAAB8eg7VZGs333.jpg


   当我自定义了模型名,然后在数据库集合中名称于此不对称,这不得不让人抓狂。如果正如猜想的那样,Collection的命名做了复数和不可数处理,那么是不是在命名一个模型(集合)名的时候,我还得考虑一下使用的名词单复数性。即使是考虑了,能否保证一致,那得看英语水平了。


  实际开发中当然希望程序中指定的模型的命名能够一致的和数据库的集合名称对应起来,那便是极好的。出于这种想法,于是探究了一下Mongoose框架的源代码,看看作者是如何做集合命名规范了,发现位于mongoose/lib/util.js模块中如下代码片段是集合命名的根源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*!
  * Produces a collection name from model `name`.
  *
  * @param {String} name a model name
  * @return {String} a collection name
  * @api private
  */
exports.toCollectionName =  function  (name, options) {
   options = options || {};
   if  ( 'system.profile'  === name)  return  name;
   if  ( 'system.indexes'  === name)  return  name;
   if  (options.pluralization ===  false return  name;
   return  pluralize(name.toLowerCase());
};
/**
  * Pluralization rules.
  *
  * These rules are applied while processing the argument to `toCollectionName`.
  *
  * @deprecated remove in 4.x gh-1350
  */
exports.pluralization = [
   [/(m)an$/gi,  '$1en' ],
   [/(pe)rson$/gi,  '$1ople' ],
   [/(child)$/gi,  '$1ren' ],
   [/^(ox)$/gi,  '$1en' ],
   [/(ax|test)is$/gi,  '$1es' ],
   [/(octop|vir)us$/gi,  '$1i' ],
   [/(alias|status)$/gi,  '$1es' ],
   [/(bu)s$/gi,  '$1ses' ],
   [/(buffal|tomat|potat)o$/gi,  '$1oes' ],
   [/([ti])um$/gi,  '$1a' ],
   [/sis$/gi,  'ses' ],
   [/(?:([^f])fe|([lr])f)$/gi,  '$1$2ves' ],
   [/(hive)$/gi,  '$1s' ],
   [/([^aeiouy]|qu)y$/gi,  '$1ies' ],
   [/(x|ch|ss|sh)$/gi,  '$1es' ],
   [/(matr|vert|ind)ix|ex$/gi,  '$1ices' ],
   [/([m|l])ouse$/gi,  '$1ice' ],
   [/(quiz)$/gi,  '$1zes' ],
   [/s$/gi,  's' ],
   [/([^a-z])$/,  '$1' ],
   [/$/gi,  's' ]
];
var  rules = exports.pluralization;
/**
  * Uncountable words.
  *
  * These words are applied while processing the argument to `toCollectionName`.
  * @api public
  */
exports.uncountables = [
   'advice' ,
   'energy' ,
   'excretion' ,
   'digestion' ,
   'cooperation' ,
   'health' ,
   'justice' ,
   'labour' ,
   'machinery' ,
   'equipment' ,
   'information' ,
   'pollution' ,
   'sewage' ,
   'paper' ,
   'money' ,
   'species' ,
   'series' ,
   'rain' ,
   'rice' ,
   'fish' ,
   'sheep' ,
   'moose' ,
   'deer' ,
   'news' ,
   'expertise' ,
   'status' ,
   'media'
];
var  uncountables = exports.uncountables;
/*!
  * Pluralize function.
  *
  * @author TJ Holowaychuk (extracted from _ext.js_)
  * @param {String} string to pluralize
  * @api private
  */
function  pluralize (str) {
//  var rule, found;
//  if (!~uncountables.indexOf(str.toLowerCase())){
//    found = rules.filter(function(rule){
//      return str.match(rule[0]);
//    });
//    if (found[0]) return str.replace(found[0][0], found[0][1]);
//  }
   return  str;
};


上面代码对集合名称做了处理,uncountables是不可数名词,rules是一组正则匹配规则。当注释掉function pluralize(str)方法中的处理代码之后,重新运行文中第一段代码,结果如下:

wKiom1NhBn3AGyukAACeqSorOVA197.jpg

        function pluralize(str)方法的处理思路是:

      1.判断模型名是否是不可数的,如果是直接返回模型名;否则进行复数转化正则匹配;

      2.返回复数转化正则匹配结果(一个复数转化正则匹配是一个数组,有两个对象,[0]正则表达式,[1]匹配后处理结果);

      3.如果复数转化正则匹配结果不存在,直接返回模型名;否则取匹配结果第一个,对模型名进行处理。(需要说明的是,rules是按特殊到一般的顺序排列的)


      不清楚作者出于什么考虑对模型名和集合名未做对应处理,第一次使用Mongoose的时侯产生了这个疑问,于是刨根问底看了个究竟。作此文,记录一下,如果真想保持是模型名和数据库中的集合名保持一致,不妨从源代码下手。

      PS:感谢作者给我们提供了一个不错的英文名词复数化的代码段。



本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1405203,如需转载请自行联系原作者

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
4月前
|
Python
无法导入名为'index'的模块
无法导入名为'index'的模块
29 2
|
Java 数据库
JPA通用策略生成器(@GeneratedValue 四种标准用法为TABLE, SEQUENCE, IDENTITY, AUTO)
JPA通用策略生成器(@GeneratedValue 四种标准用法为TABLE, SEQUENCE, IDENTITY, AUTO)
145 0
|
JSON JavaScript 前端开发
Ember Data 之模型定义
前面在《 Ember.js 项目开发之 Ember Data 》介绍了Ember Data,本文将继续介绍模型的定义。
72 0
|
数据库
一对多关系domain Model中设置使用AutoMapper时出错
一对多关系domain Model中设置使用AutoMapper时出错
143 0
一对多关系domain Model中设置使用AutoMapper时出错
|
PHP
【laravel】使用模型的create方法添加数据
【laravel】使用模型的create方法添加数据
384 0
【laravel】使用模型的create方法添加数据
|
IDE API 开发工具
FastAPI(14)- 路径操作函数参数的类型是一个嵌套 Pydantic Model 的使用场景
FastAPI(14)- 路径操作函数参数的类型是一个嵌套 Pydantic Model 的使用场景
163 0
FastAPI(14)- 路径操作函数参数的类型是一个嵌套 Pydantic Model 的使用场景
FastAPI(22)- Pydantic Model 结合 Union、List 的使用场景
FastAPI(22)- Pydantic Model 结合 Union、List 的使用场景
432 0
FastAPI(22)- Pydantic Model 结合 Union、List 的使用场景
|
程序员 Python
python模块与类库(创建、导入与使用逻辑,子模块,if __name__ ==‘main‘: 语句, __name__,__dict__,__doc__,__file__等)
python模块与类库(创建、导入与使用逻辑,子模块,if __name__ ==‘main‘: 语句, __name__,__dict__,__doc__,__file__等)
214 0
python模块与类库(创建、导入与使用逻辑,子模块,if __name__ ==‘main‘: 语句, __name__,__dict__,__doc__,__file__等)