1.mongoose schema

[SchemaTypes]

模式类型处理路径默认值、验证、getter、setter、字段选择默认值以及字符串和数字的其他一般特征。

以下是所有的有效SchemaTypes的mongoose。

  • [字符串]
  • [数量]
  • [日期]
  • [缓冲]
  • 布尔
  • 混合
  • [ObjectId]
  • [数组]
  • Decimal128
  • [Map]

例子

var schema = new Schema({
  name:    String,
  binary:  Buffer,
  living:  Boolean,
  updated: { type: Date, default: Date.now },
  age:     { type: Number, min: 18, max: 65 },
  mixed:   Schema.Types.Mixed,
  _someId: Schema.Types.ObjectId,
  decimal: Schema.Types.Decimal128,
  array: [],
  ofString: [String],
  ofNumber: [Number],
  ofDates: [Date],
  ofBuffer: [Buffer],
  ofBoolean: [Boolean],
  ofMixed: [Schema.Types.Mixed],
  ofObjectId: [Schema.Types.ObjectId],
  ofArrays: [[]],
  ofArrayOfNumbers: [[Number]],
  nested: {
    stuff: { type: String, lowercase: true, trim: true }
  },
  map: Map,
  mapOfString: {
    type: Map,
    of: String
  }
})

// example usevar Thing = mongoose.model('Thing', schema);

var m = new Thing;
m.name = 'Statue of Liberty';
m.age = 125;
m.updated = newDate;
m.binary = new Buffer(0);
m.living = false;
m.mixed = { any: { thing: 'i want' } };
m.markModified('mixed');
m._someId = new mongoose.Types.ObjectId;
m.array.push(1);
m.ofString.push("strings!");
m.ofNumber.unshift(1,2,3,4);
m.ofDates.addToSet(newDate);
m.ofBuffer.pop();
m.ofMixed = [1, [], 'three', { four: 5 }];
m.nested.stuff = 'good';
m.map = newMap([['key', 'value']]);
m.save(callback);

[SchemaType选项]

您可以使用类型直接声明模式类型,或者具有类型属性的对象。

var schema1 = new Schema({
  test: String// `test` is a path of type String
});

var schema2 = new Schema({
  test: { type: String } // `test` is a path of type string
});

除了类型属性,你可以指定路径的附加属性。例如,如果你想要小写保存前一个字符串:

var schema2 = new Schema({
  test: {
    type: String,
    lowercase: true// Always convert `test` to lowercase
  }
});

lowercase只适用于字符串属性。有一些适用于所有模式类型的选项,以及一些适用于特定模式类型的选项。

所有模式类型
  • required:布尔或函数,如果真正的添加一个[需要验证器]为这个属性
  • default:任何或函数,设置一个默认值的路径。如果该值是一个函数,函数的返回值作为默认值。
  • select:布尔,指定默认值[预测]查询
  • validate:添加一个函数[验证器函数]为这个属性
  • get:函数,定义了该属性使用一个定制的getter
  • set:函数,定义了该属性使用一个定制的setter
  • alias:字符串,mongoose> = 4.10.0。定义了一个[virtual]的名字拿到/设置这个path。
var numberSchema = new Schema({
  integerOnly: {
    type: Number,
    get: v => Math.round(v),
    set: v => Math.round(v),
    alias: 'i'
  }
});

varNumber = mongoose.model('Number', numberSchema);

var doc = newNumber();
doc.integerOnly = 2.001;
doc.integerOnly; // 2
doc.i; // 2
doc.i = 3.001;
doc.integerOnly; // 3
doc.i; // 3
索引

您还可以定义[MongoDB索引]使用模式类型的选择。

  • index:布尔,是否要定义一个[指数]在这个属性。
  • unique:布尔,是否要定义一个[唯一索引]在这个属性。
  • sparse:布尔,是否要定义一个[稀疏索引]在这个属性。
var schema2 = new Schema({
  test: {
    type: String,
    index: true,
    unique: true// Unique index. If you specify `unique: true`// specifying `index: true` is optional if you do `unique: true`
  }
});

字符串
  • lowercase:布尔,是否总是为这个值调用.toLowerCase()方法
  • uppercase:布尔,是否总是为这个值调用.toUpperCase()方法
  • trim:布尔,是否总是为这个值调用.trim()方法
  • match:创建一个正则表达式[验证器]检查如果匹配给定的正则表达式的值
  • enum:创建一个数组[验证器]检查值是否在给定的数组。
  • minlength:Number类型,创建一个[验证器]检查值长度是不是少于给定的数字
  • maxlength:Number类型,创建一个[验证器]检查值长度不大于给定的数字
数量
  • min:Number类型,创建一个[验证器]检查如果该值大于或等于给定的最小值。
  • max:Number类型,创建一个[验证器]检查值是否小于或等于给定的最大值。
日期
  • min:Date类型
  • max:Date类型

[使用笔记]

日期

内置的日期方法不会被连接到mongoose的变化跟踪逻辑中,在英语中,如果你在你的文档中使用一个日期,并使用setMonth()这样的方法修改它,那么mongoose将不会意识到这个变化,而doc.save()将不会这种修改。
如果您必须使用内置的方法修改日期类型,请在保存之前告诉mongoose关于更改的(“pathToYourDate”)。

var Assignment = mongoose.model('Assignment', { dueDate: Date });
Assignment.findOne(function (err, doc) {
  doc.dueDate.setMonth(3);
  doc.save(callback); // THIS DOES NOT SAVE YOUR CHANGE

  doc.markModified('dueDate');
  doc.save(callback); // works
})

混合

SchemaType“怎么都行”,其灵活性的平衡是很难维护。混合可以是以下三种任何模式:Schema.Types、或通过传递一个空对象。以下是等价的:

var Any = new Schema({ any: {} });
var Any = new Schema({ any: Object });
var Any = new Schema({ any: Schema.Types.Mixed });

因为它是一种非模式化,你可以改变任何你喜欢的价值,但mongoose失去了能够自动检测并保存这些更改。“告诉”mongoose混合型的值发生了变化,调用.markModified(path)方法混合类型文档的传递路径就改变了。

person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved

objectid

指定一个类型的ObjectId,使用Schema.Types.ObjectId在你的类型声明中。

var mongoose = require('mongoose');
var ObjectId = mongoose.Schema.Types.ObjectId;
var Car = new Schema({ driver: ObjectId });
// or just Schema.ObjectId for backwards compatibility with v2

数组

提供创建数组[SchemaTypes];)或[子文档]

var ToySchema = new Schema({ name: String });
var ToyBox = new Schema({
  toys: [ToySchema],
  buffers: [Buffer],
  string:  [String],
  numbers: [Number]
  // ... etc
});

数组是特殊的,因为他们暗中有默认值[](空数组)。

var Toy = mongoose.model('Test', ToySchema);
console.log((new Toy()).toys); // []

覆盖这个默认情况下,您需要设置默认值undefined

var ToySchema = new Schema({
  toys: {
    type: [ToySchema],
    default: undefined
  }
});

注:指定一个空数组相当于Mixed。以下所有创建数组类型为Mixed:

var Empty1 = new Schema({ any: [] });
var Empty2 = new Schema({ any: Array });
var Empty3 = new Schema({ any: [Schema.Types.Mixed] });
var Empty4 = new Schema({ any: [{}] });

Map

mongoose5.1.0

一个MongooseMap是内置的一个子类[Map类]。在这些文档,我们将使用术语“Map”和MongooseMap互换。在mongoose,Map是你如何去创建一个嵌套文档的任意键。

const userSchema = new Schema({
  // `socialMediaHandles` is a map whose values are strings. A map's// keys are always strings. You specify the type of values using `of`.
  socialMediaHandles: {
    type: Map,
    of: String
  }
});

const User = mongoose.model('User', userSchema);
// Map { 'github' => 'vkarpov15', 'twitter' => '@code_barbarian' }console.log(new User({
  socialMediaHandles: {
    github: 'vkarpov15',
    twitter: '@code_barbarian'
  }
}).socialMediaHandles);

上面的例子中没有显式地声明githubtwitter路径,但是,因为socialMediaHandles是一个map,您可以存储任意键/值对。然而,由于socialMediaHandles是map,您必须使用.get()一个关键的值的“key”和.set()设置一个关键的值的“key”。

const user = new User({
  socialMediaHandles: {}
});

// Good
user.socialMediaHandles.set('github', 'vkarpov15');

// Works too
user.set('socialMediaHandles.twitter', '@code_barbarian');

// Bad, the `myspace` property will **not** get saved
user.socialMediaHandles.myspace = 'fail';

// 'vkarpov15'
console.log(user.socialMediaHandles.get('github'));

// '@code_barbarian'
console.log(user.get('socialMediaHandles.twitter'));

// undefined
user.socialMediaHandles.github;

// Will only save the 'github' and 'twitter' properties
user.save();

在MongoDB中,Map类型被存储为BSON对象。
BSON对象中的键是有序的,因此这意味着保留了map的插入顺序属性。

[创建自定义类型]

mongoose也可以通过自定义SchemaTypes扩展。搜索[插件]网站兼容的类型,[其他])[类型]

[schema.path()函数]

schema.path()函数返回给定路径的模式类型实例化。

var sampleSchema = new Schema({ name: { type: String, required: true } });
console.log(sampleSchema.path('name'));
// Output looks like:/**
 * SchemaString {
 *   enumValues: [],
 *   regExp: null,
 *   path: 'name',
 *   instance: 'String',
 *   validators: ...
 */

您可以使用此函数检查给定路径的模式类型,包括验证器和类型是什么。

[接下来]

现在我们已经介绍了SchemaTypes,接下来让我们看一下connections

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,212评论 0 4
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,732评论 2 9
  •   引用类型的值(对象)是引用类型的一个实例。   在 ECMAscript 中,引用类型是一种数据结构,用于将数...
    霜天晓阅读 1,036评论 0 1
  • 我想要成为的唯一 妈妈最爱最关心的女儿 爷奶最疼的孙女 好友aa最亲密的朋友,足够的重视 男票最难忘,最深爱的女人...
    runningbubu阅读 186评论 0 0