[原译]在mongoose中对Array Schema进行增删改
原文地址: http://tech-blog.maddyzone.com/node/add-update-delete-object-array-schema-mongoosemongodb
本文为上面文章的翻译版本,以学习和锻炼为宗旨,文中一些术语为了避免歧义保留英文名称
大多数情况下,我们使用node.js的时候会使用MongoDB, 然后在写MongoDB相关的验证、转换和业务逻辑时我们会经常使用Mongoose。 这里我分享一些关于Array Schema的使用技巧。 当你读完这篇文章的时候,你将了解如何在Mongoose中增加、更新和删除一个Array Schema中的对象。
本文将涵盖:
- 如何在Mongoose中定义Array Schema
- 如何在Mongoose中向Array Schema增加一个值或者对象
- 如何在Mongoose中更新Array Schema中的一个值或者对象
- 如何在Mongoose中删除Array Schema中的一个值或者对象
Ok, Lest' Start.
1. 如何在Mongoose中定义Array Schema
首先,我们要定义一个基本的名为Article的Mongoose Schema。 这里我们将Comments定义为一个Array Schema类型。 不必要关注于所有的代码,只需要关注在Comments,这是本文讨论的重点。

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
/**
 * Article Schema
 */
var ArticleSchema = new Schema({
  title: {type:String, required:true},
  createdAt: { type: Date, default: Date.now },
  description:{type:String, required:true},
  tags: [String],
  comments: [{ post: String,
               posted: {type: Date, default: Date.now}
             }]
});
mongoose.model('Article', ArticleSchema);
这里我们假设我们已经在article集合中创建了一些向下面这样的数据,现在还没有任何comments:
{
 "_id" : ObjectId("54fcb3890cba9c4234f5c925"),
 "title" : "A test Article",
 "description" : "test article description",
 "tags" : [
 "test tag"
 ],
 "createdAt" : ISODate("2015-03-08T20:39:37.980Z")
 }
2.如何在Mongoose中向Array Schema增加一个值或者对象
当我们添加了一个article后,我们应该可以向comments中添加任意数量的数据。比如当有新的评论时,我们要将该条评论添加到comments属性中,我们看如何做。
假设请求中我们可以拿到articleid用来指定需要向哪个article中添加评论,POST的地址像下面这样:
/api/comments/:articleid
接下来按下面的方式来操作,我们使用了findByIdAndUpdate
假设请求的参数中articleid是54fcb3890cba9c4234f5c925 
var article_id = req.params.articleid;/** assume here we get 54fcb3890cba9c4234f5c925 id
    of article as shown in our demo json bve
     "_id" : ObjectId("54fcb3890cba9c4234f5c925"),
     **/
    /** assume your req.body like is below
        you can set your logic your own ways
        for this article i am assuming that data
        would come like below
    **/
    //req.body={post: "this is the test comments"};
     Article.findByIdAndUpdate(
     article_id,
     { $push: {"comments": req.body}},
     {  safe: true, upsert: true},
       function(err, model) {
         if(err){
        	console.log(err);
        	return res.send(err);
         }
          return res.json(model);
      });
主要是使用下面这行代码我们就可以将数据插入到Array Schema:
{ $push: {"comments": req.body}}
上面的操作执行之后,在MongoDB中的数据如下:
{
 "_id" : ObjectId("54fcb3890cba9c4234f5c925"),
 "title" : "A test Article",
 "description" : "test article description",
 "tags" : [
 "test tag"
],
 "createdAt" : ISODate("2015-03-08T20:39:37.980Z"),
 "comments" : [
 {
 "post" : "this is the test comments",
 "_id" : ObjectId("54fe0976250888001d5e6bc4"),
 "posted" : ISODate("2015-03-09T20:58:30.302Z")
 }
 ]
}
3.如何在Mongoose中更新Array Schema中的一个值或者对象
对于更新操作,我们假设请求中带有articleid和commentid,来定位我们想更新哪个article中的哪个comment.
PUT地址像下面这样:
/api/comments/:articleid/:commentid
更新代码:
 Article.update({'comments._id': comment_id},
      {'$set': {
             'comments.$.post': "this is Update comment",
	   }},
          function(err,model) {
	   	if(err){
        	console.log(err);
        	return res.send(err);
        }
        return res.json(model);
 });
现在再看下MongoDB中的数据:
{
 "_id" : ObjectId("54fcb3890cba9c4234f5c925"),
 "title" : "A test Article",
 "description" : "test article description",
 "tags" : [
 "test tag"
 ],
 "createdAt" : ISODate("2015-03-08T20:39:37.980Z"),
 "comments" : [
 {
 "post" : "this is Update comment",
 "_id" : ObjectId("54fe0976250888001d5e6bc4"),
 "posted" : ISODate("2015-03-09T20:58:30.302Z")
 }
 ]
}
所以使用下面这样的代码可以更新Array Schema的数据:
{'$set': {
 'comments.$.post': "this is Update comment",
 }},
4.如何在Mongoose中删除Array Schema中的一个值或者对象
和更新一样,假设请求中有articleid和commentid,来定位我们想删除哪个article中的哪个comment.
DELETE地址如下:
/api/comments/:articleid/:commentid
跟上面的操作一样,我们使用findByIdAndUpate方法:
var article_id = req.params.articleid,//assume get 54fcb3890cba9c4234f5c925
    comment_id = req.params.commentid;// assume get 54fcb3890cba9c4234f5c925
  Article.findByIdAndUpdate(
    article_id,
   { $pull: { 'comments': {  _id: comment_id } } },function(err,model){
      if(err){
       	console.log(err);
       	return res.send(err);
        }
        return res.json(model);
    });
执行之后,查看数据库中的数据:
{
 "_id" : ObjectId("54fcb3890cba9c4234f5c925"),
 "title" : "A test Article",
 "description" : "test article description",
 "tags" : [
 "test tag"
 ],
 "createdAt" : ISODate("2015-03-08T20:39:37.980Z"),
 "comments" : []//remove comments
}
使用下面的代码可以删除Array Schema中的数据:
{ $pull: { 'comments': { _id: comment_id } } }
总结

[原译]在mongoose中对Array Schema进行增删改的更多相关文章
- JS中对数组元素进行增删改移
		在js中对数组元素进行增删改移,简单总结了一下方法: 方法 说明 实例 push( ); 在原来数组中的元素最后面添加元素 arr.push("再见58"); unshift( ) ... 
- kibana的Dev Tool中如何对es进行增删改查
		kinaba Dev Tool中对es(elasticSearch)进行增删改查 一.查询操作 查询语句基本语法 以下语句类似于mysql的: select * from xxx.yyy.topic ... 
- 在ASP.NET MVC中对表进行通用的增删改
		http://www.cnblogs.com/nuaalfm/archive/2009/11/11/1600811.html 预备知识: 1.了解反射技术 2.了解C#3.0中扩展方法,分布类,Lin ... 
- Django中对单表的增删改查
		之前的简单预习,重点在后面 方式一: # create方法的返回值book_obj就是插入book表中的python葵花宝典这本书籍纪录对象 book_obj=Book.objects.creat ... 
- Django学习笔记--数据库中的单表操作----增删改查
		1.Django数据库中的增删改查 1.添加表和字段 # 创建的表的名字为app的名称拼接类名 class User(models.Model): # id字段 自增 是主键 id = models. ... 
- Django中ORM对数据库的增删改查操作
		前言 什么是ORM? ORM(对象关系映射)指用面向对象的方法处理数据库中的创建表以及数据的增删改查等操作. 简而言之,就是将数据库的一张表当作一个类,数据库中的每一条记录当作一个对象.在 ... 
- (数据科学学习手札126)Python中JSON结构数据的高效增删改操作
		本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在上一期文章中我们一起学习了在Python ... 
- Django中ORM对数据库的增删改查
		Django中ORM对数据库数据的增删改查 模板语言 {% for line in press %} {% line.name %} {% endfor %} {% if 条件 %}{% else % ... 
- mongoose 的 model,query:增删改查
		简介 mongoose是node.js的一个操作mongodb的模块,比起之前mongodb模块,只需要在开始时连接,不需要手动关闭,十分方便. 连接mongodb 首先你需要安装mongodb.有了 ... 
随机推荐
- 轻型ORM--Dapper
			分享一个轻型ORM--Dapper选用理由 推荐理由:Dapper只有一个代码文件,完全开源,你可以放在项目里的任何位置,来实现数据到对象的ORM操作,体积小速度快:) Google Code下载地址 ... 
- 快速构建Windows 8风格应用31-构建磁贴
			原文:快速构建Windows 8风格应用31-构建磁贴 引言 磁贴是吸引用户经常使用应用重要手段之一.我们可将应用程序内较好的内容使用磁贴进行展示. 另外应用程序磁贴是应用程序中的核心部分,而且很可能 ... 
- POJ 3624 Charm Bracelet 背包问题的解决方案
			最简单的背包问题,标题应该是除了背包测试中心:您无法打开二维数组.我还没有开的二维.光看数据是不可能的. 太大. 有两种方法来提高全省内存DP: 1 所谓卷的阵列 2 反向表 久没做背包DP,突然认为 ... 
- 华硕K55DR体验 - 显卡就是坑
			朋友拿来电脑,本来他室友已经把他电脑重做完了,但还是卡,非要给我再搞一遍,难道?我就是传说中的大神?咳咳...YY一下,适可而止 华硕K55DR的配置来看,似乎应付CF没什么问题,可是,FPS各种不稳 ... 
- C/C++中常量字符串管理
			为了节省内存,C/C++把常量字符串放到单独的一个内存区域.当几个指针赋值给相同的常量字符串时,它们实际上会指向相同的内存地址.但用产量初始化字符数组,结果却不同. 下面是一个小程序示例: #incl ... 
- [译]Java 设计模式之工厂
			(文章翻译自Java Design Pattern: Factory) 1.Java工厂模式的来历 工厂设计模式用于创建基于不同参数的对象.下面的例子就是在一个工厂里创建一个人.如果我们向工厂要一个b ... 
- leetcode第18题--Letter Combinations of a Phone Number
			Problem: Given a digit string, return all possible letter combinations that the number could represe ... 
- Wijmo 5 + Ionic Framework之:Hello World!
			Wijmo 5 + Ionic Framework之:Hello World! 本教程中,我们用Wijmo 5 和 Ionic Framework实现一个Mobile的工程:Hello World. ... 
- sbt公布assembly解决jar包冲突 deduplicate: different file contents found in the following
			一个.问题定义 近期使用sbt战斗assembly发生故障时,包,在package什么时候,发生jar包冲突/文件冲突,两个相同class来自不同jar包classpath内心冲突. 有关详细信息:我 ... 
- 自己动手实现Expression翻译器 – Part Ⅲ
			上一节实现了对TableExpression的解析,通过反射创建实例以及构建该实例的成员访问表达式生成了一个TableExpression,并将其遍历格式化为”Select * From TableN ... 
