文档章节

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

secondriver
 secondriver
发布于 2015/09/17 09:12
字数 1368
阅读 38
收藏 0

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

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模块中如下代码片段是集合命名的根源。

/*!
 * 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
粉丝 10
博文 229
码字总数 233821
作品 0
广州
程序员
私信 提问
Node.JS -- Mongoose 快速入门

Mongoose时一个用于异步环境的MongoDB的对象模型。 前提条件 先确保本地已经安装了Node.js和一个可以连接上的MongoDB。 安装Mongoose Mongoose和其他的依赖模块一样安装,使用npm 命令: 连接...

米阳MeYoung
2018/06/04
0
0
node的Mongodb使用(mongoose)

1. 首先安装模块 运行 2. 添加数据库连接配置文件 3. 编写model模块,以user为例 schema是mongoose里会用到的一种数据模式,可以理解为表结构的定义;每个schema会映射到mongodb中的一个col...

stutterr
2017/12/03
0
0
Node.js开发入门——MongoDB与Mongoose

为了保存网站的用户数据和业务数据,通常需要一个数据库。MongoDB和Node.js特别般配,因为MongoDB是基于文档的非关系型数据库,文档是按BSON(JSON的轻量化二进制格式)存储的,增删改查等管...

foruok
2015/08/18
0
0
Nodejs和Mongodb的连接器Mongoose

简介 今天我们将学习Mongoose,什么是Mongoose呢,它于MongoDB又是什么关系呢,它可以用来做什么呢,介绍Mongoose之前,我们先简单了解一下MongoDB。 MongoDB是一个开源的NoSQL数据库,相比M...

笔阁
2015/10/13
306
0
Mongoose,nodejs和mongodb的连接器。

简介 今天我们将学习Mongoose,什么是Mongoose呢,它于MongoDB又是什么关系呢,它可以用来做什么呢,介绍Mongoose之前,我们先简单了解一下MongoDB。 MongoDB是一个开源的NoSQL数据库,相比M...

笔阁
2015/10/13
2.4K
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
6
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
4
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
7
0
从零基础到拿到网易Java实习offer,我做对了哪些事

作为一个非科班小白,我在读研期间基本是自学Java,从一开始几乎零基础,只有一点点数据结构和Java方面的基础,到最终获得网易游戏的Java实习offer,我大概用了半年左右的时间。本文将会讲到...

Java技术江湖
昨天
7
0
程序性能checklist

程序性能checklist

Moks角木
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部