首先确定你安装了MongoDB和Node.js.
然后用如下命令安装 Mongoose 。
npm install mongoose
现在假设我们喜欢毛绒玩具。把我们遇到的毛绒玩具都记录到 MongoDB里。我们需要做的第一件事就是在我们的项目包含mongoose ,然后在本地MongoDB运行实例上打开一个 test database。
// getting-started.js
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) {
// yay!
});
每次打开连接后,回调函数都会被执行。为了简单起见,我们假设所有代码都在这个回调中。
在mongoose中,所有东西都是由Schema得来,我们参考着做一个,定义我们的小猫。
var kittySchema = mongoose.Schema({
name: String
})
目前为止一切都很顺利。我们得到了一个带有一个属性“name”的schema,这个“name”会是一个字符串。下一步是把schema编译到一个Model.
var Kitten = mongoose.model('Kitten', kittySchema)
model是一个用于构造document的类。在这种情况下,每个document都会是一只带有我们在模式中声明的属性和行为的小猫。让我们创建一个小猫的文档代表我们刚才在大街上遇到 一个小家伙。
var silence = new Kitten({ name: 'Silence' })
console.log(silence.name) // 'Silence'
小猫可以喵喵叫,所以,我们来看看如何给document创建一个说话的功能
// 注意: methods必须在schema被mongoose.model编译前添加到schema。
kittySchema.methods.speak = function () {
var greeting = this.name
? "Meow name is " + this.name
: "I don't have a name"
console.log(greeting);
}
var Kitten = mongoose.model('Kitten', kittySchema)
添加到schema的methods的属性的这个函数会编译成model原型,暴露给每个文档实例:
var fluffy = new Kitten({ name: 'fluffy' });
fluffy.speak() // "喵出名字叫fluffy"
我们有会说话的小猫!但是我们仍然没有保存任何东西到MongoDB 。每个文档通过调用它的save方法都可以保存到数据库。回调的第一个参数是一个错误如果有的话。
fluffy.save(function (err, fluffy) {
if (err) return console.error(err);
fluffy.speak();
});
随着时间的流逝,我们想看看我们遇到过的所有的小猫。通过Kitten model我们可以访问所有的小猫。
Kitten.find(function (err, kittens) {
if (err) return console.error(err);
console.log(kittens)
})
我们只是打印了db中所有的小猫到控制台。如果我们想要通过名字筛选小猫,mongoose支持mongoDB丰富的查询语法。
Kitten.find({ name: /^Fluff/ }, callback)
上面的代码会执行一个查找,查找所有名字以“Fluff”开头的小猫,并在回调函数中返回。
这里我们结束了快速上手之旅。
我们创建了一个schema,添加一个自定义文档的method,用Mongoose保存并查找了MongoDB。查询的小猫。去指导或API文档。写在引导或者API之前。
Q.为什么我修改了数组,直接更新元素保存不了?
doc.array[3] = 'changed';
doc.save();
A.Mongoose不为数组索引创建etters/setters方法。没有它们mongoose从来得不到变化通知,所以不知道存留新的值。解决方法是使用 3.2.0版本以上的MongooseArray的set方法。
// 3.2.0
doc.array.set(3, 'changed');
doc.save();
// if running a version less than 3.2.0, you must mark the array modified before saving.
doc.array[3] = 'changed';
doc.markModified('array');
doc.save();
Q.为什么mongoose不允许我直接指定schema到一个路径 呢?
var userSchema = new Schema({ name: String });
new Schema({ user: userSchema })
A.Schemas与document有一个一对一的映射.随同它们(如下面这样的)自己的pre和post钩子一起,文档拥有save和remove方法。
doc.user.save(); // ?
doc.user.remove();// ?
doc.save()
我们认为,这个API将是困惑多于帮助。与之相反的观点认为子文档的数组已经有了这个功能,但是充其量这导致了许多混乱。在未来,这很可能会重新考虑。
Q. 怎么调试呢?
A.设置调试模式为true.
mongoose.set('debug', true)
所有已执行的collections方法会将其参数输出到控制台。
Q. 我的save()回调从来没有执行过。我这是哪时出错了呢?
A.所有集合的方法(insert,remove,queries等等)都会在连接打开之前排成队列。很可能尝试连接时出错。尝试把错误处理添加到您的连接。
// 如果连接到默认连接上
mongoose.connect(..);
mongoose.connection.on('error', handleError);
// 如果连接到分支连接上
var conn = mongoose.createConnection(..);
conn.on('error', handleError);
Q.我是否应该为每一个数据库操作创建或者销毁一个新的连接?
A.No,打开连接时,您的应用程序启动并保持打开,直到应用程序关闭。
还有补充的吗?
如果你想贡献资料,你就贡献资料吧。