《mongdb》学习开发笔记

1.《MongoDB教程 菜鸟教程》

(1)https://www.runoob.com/mongodb/mongodb-tutorial.html
(2)https://www.mongodb.org.cn/drivers/
这个是基础,在mongoshell下对mongoDB直接操作,为以后的node.jsAPI操作打下基础
另外mongoDB在应用程序中需要不同的驱动来操作mongoDB,链接(2)中可以选择不同的语言驱动
C,C++,Perl,Jave,Node.js,C#,.NET,PHP

note: 个人觉得比官网写得好

2.《Node.js教程 》

(1)https://www.runoob.com/nodejs/nodejs-mongodb.html《菜鸟教程》
(2)http://nodejs.cn/learn《官网教程》
note:个人建议先学菜鸟,基础够多,够详细
然后再看官网教程,进行补充
Node.js 不同环境下的安装是一个难题,尤其是嵌入式平台,祝大家好运

3.《mongoose.js教程》

那么要使用它,首先你得装上node.js和mongodb
Mongoose是在node.js异步环境下对mongodb进行便捷操作的对象模型工具
(1)http://cw.hubwiz.com/card/c/543b2e7788dba02718b5a4bd/1/1/2/《汇智网络教程》
(2)https://mongoosejs.com/docs/index.html《官网教程》
note:这两个教程各有千秋,
个人建议先(1),基础够多,够详细
然后再看官网教程,进行补充

4 mongodb $unwind 聚合管道

$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
需求:

{
    "_id" : ObjectId("5951c5de567ebff0d5011fba"),
    "name" : "陈晓婵",
    "address" : "北京朝阳区",
    "weekday" : [ 
        1, 
        2, 
        3, 
        4, 
        5
    ]
}

weekday进行拆分:

db.getCollection('chenxiaochantest').aggregate(
 [
  {
     $unwind:"$weekday"
  }
 ]
)

拆分结果:使用**$unwind可以将weekday**中的每个数据都被分解成一个文档,并且除了weekday的值不同外,其他的值都是相同的.

/* 1 */
{
    "_id" : ObjectId("5951c5de567ebff0d5011fba"),
    "name" : "陈晓婵",
    "address" : "北京朝阳区",
    "weekday" : 1
}
 
/* 2 */
{
    "_id" : ObjectId("5951c5de567ebff0d5011fba"),
    "name" : "陈晓婵",
    "address" : "北京朝阳区",
    "weekday" : 2
}
 
/* 3 */
{
    "_id" : ObjectId("5951c5de567ebff0d5011fba"),
    "name" : "陈晓婵",
    "address" : "北京朝阳区",
    "weekday" : 3
}
 
/* 4 */
{
    "_id" : ObjectId("5951c5de567ebff0d5011fba"),
    "name" : "陈晓婵",
    "address" : "北京朝阳区",
    "weekday" : 4
}
 
/* 5 */
{
    "_id" : ObjectId("5951c5de567ebff0d5011fba"),
    "name" : "陈晓婵",
    "address" : "北京朝阳区",
    "weekday" : 5
}

5 MongoDB 聚合操作 $group 使用

语法

{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }

参数说明:

_id :强制必须存在。可以为 null。

其余的计算字段是可选的,并使用运算符计算。具体的使用,通过下面的代码说明:
首先准备一点数据:
// 插入数据

db.getCollection('sales').insertMany([
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") },
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") },
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") },
{ "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") },
{ "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }
]);

示例:按照 item 字段进行分组,统计每个 item 下面的文档个数

db.sales.aggregate([
    {
        $group : {
            _id : "$item",
            count: { $sum : 1}
        }
    }
]);
 
// 返回结果
{ "_id" : "xyz", "count" : 2 }
{ "_id" : "jkl", "count" : 1 }
{ "_id" : "abc", "count" : 2 }

示例:按照 item 字段进行分组,统计每个 item 下面 price 的总数,quantity 的平均数

db.sales.aggregate([
    {
        $group : {
            _id : "$item",
            totalPrice: { $sum : "$price"},
            avgQuantity: { $avg: "$quantity" }
        }
    }
]);
 
// 返回结果
{ "_id" : "xyz", "totalPrice" : 10, "avgQuantity" : 15 }
{ "_id" : "jkl", "totalPrice" : 20, "avgQuantity" : 1 }
{ "_id" : "abc", "totalPrice" : 20, "avgQuantity" : 6 }

示例:按照 item 字段进行分组,统计每个 item 下面 quantity 的最大值与最小值

db.sales.aggregate([
    {
        $group : {
            _id : "$item",
            maxQuantity: { $max : "$quantity"},
            minQuantity: { $min: "$quantity" }
        }
    }
]);
 
// 返回结果
{ "_id" : "xyz", "maxQuantity" : 20, "minQuantity" : 10 }
{ "_id" : "jkl", "maxQuantity" : 1, "minQuantity" : 1 }
{ "_id" : "abc", "maxQuantity" : 10, "minQuantity" : 2 }

*示例:保留第一个内容与保留最后一个内容

db.sales.aggregate([
    {
        $group : {
            _id : "$item",
            first: { $first : "$quantity"},
        }
    }
]);
 
// 返回结果
{ "_id" : "xyz", "first" : 10 }
{ "_id" : "jkl", "first" : 1 }
{ "_id" : "abc", "first" : 2 }
db.sales.aggregate([
    {
        $group : {
            _id : "$item",
            last: { $last : "$quantity"},
        }
    }
]);
 
// 返回结果
{ "_id" : "xyz", "last" : 20 }
{ "_id" : "jkl", "last" : 1 }
{ "_id" : "abc", "last" : 10 }

示例:按月,日和年对文档进行分组,并计算总价格和平均数量,并计算每个组的文档个数

​​​​​​db.sales.aggregate([
  {
    $group : {
       // _id : { filed : value } 这个结构是自定义,用来定义按照什么分组
       // "$date" 表示操作这个字段, $month、$dayOfMonth 和 $year 是表示从 $date 里面取出对应日期数据
       _id : { month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } },
       
       // [ "$price", "$quantity" ] 指的是操作这两个数据,$multiply 对多个字段进行求和操作
       totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
       
       // "$quantity" 值的是操作这个数据,$avg 来求平均数
      averageQuantity: { $avg: "$quantity" },
      // 统计有几条集合数据
      count: { $sum: 1 }
    }
  }
]);
 
// 返回结果:
{ "_id" : { "month" : 4, "day" : 4, "year" : 2014 }, "totalPrice" : 200, "averageQuantity" : 15, "count" : 2 }
{ "_id" : { "month" : 3, "day" : 15, "year" : 2014 }, "totalPrice" : 50, "averageQuantity" : 10, "count" : 1 }
{ "_id" : { "month" : 3, "day" : 1, "year" : 2014 }, "totalPrice" : 40, "averageQuantity" : 1.5, "count" : 2 }

5.1特殊的操作方式

除了上面一种操作之后,官方还介绍了另外一操作方式

// 数据如下
{ "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }
{ "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }
{ "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
{ "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }
{ "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }

示例一: 使用 $push 操作,将数据拼接到一个数组中

// 按照 author 分组,将同一个 author 的title 拼接到一个数组中
db.books.aggregate(
   [
     { $group : { _id : "$author", books: { $push: "$title" } } }
   ]
);
 
// 返回结果
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }

在上面的操作中存在一个问题,如果是存在重复的数据,重复的数据也会一起放入到返回的结果中,对于这样子的情况使用以下操作:
// 使用 $addToSet 操作

db.books.aggregate(
   [
     { $group : { _id : "$author", books: { $addToSet: "$title" } } }
   ]
);

示例二: 使用 $$ROOT (系统变量)操作

返回生成的文档不得超过BSON文档大小限制。

// 查询操作
db.books.aggregate(
   [
     { $group : { _id : "$author", books: { $push: "$$ROOT" } } }
   ]
)
 
// 返回结果
{
  "_id" : "Homer",
  "books" :
     [
       { "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 },
       { "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 }
     ]
}
 
{
  "_id" : "Dante",
  "books" :
     [
       { "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 },
       { "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 },
       { "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }
     ]
}

6 mongodb 内嵌数组 操作符 $slice 用法

假设一个文档的内嵌数组 arr 长度为10,其中数据 分别是 1-10 :

{
    _id:1000,
    arr : {
        1,2,3,4,5,6,7,8,9,10
    }
}

现在来说明 $slice 用法:

正常用法和 limit 分页查询 区别不大 如

db.col.find( {_id:1000},
    {
        "arr":{
            $slice : [0,5]
         } 
    }
)

    结果为 1,2,3,4,5

下面看看 倒序取值

db.col.find( {_id:1000},
    {
        "arr":{
            $slice : [-1,5]
         } 
    }
)
结果为 10
db.col.find( {_id:1000},
    {
        "arr":{
            $slice : [-5,5]
         } 
    }
    )
    结果为 6 7 8 9 10

6 mongodb查询返回数组中指定数组对象

MongoDB提供了: $elemMatch, $slice, and $. 操作符来返回指定数组数据.

以下示例通过$slice操作符返回数组中最后一个数据.

db.inventory.find( { status: “A” }, { name: 1, status: 1, instock: { $slice: -1 } } )

$elemMatch, $slice, and $这三个操作符是唯一的方式来指定返回数组中的数据, 你不能指定数组索引来返回数组中的数据.例如{ “instock.0”: 1 }不会返回数组中的第一个元素.

7 指定数组位置:

在这里插入图片描述对num:12 进行+2,该如何操作呢?

$ :会记住查询结果的位置。

db.ArrayTest.updateOne({“address.street”: “JingKe”},{KaTeX parse error: Expected '}', got 'EOF' at end of input: inc: {"address..num": 2}})
在这里插入图片描述

8 MongoDB 数组元素增删改

1、占位符$

占位符$的作用主要是用于返回数组中第一个匹配的数组元素值(子集),重点是第一个
在更新时未显示指定数组中元素位置的情形下,占位符$用于识别元素的位置
通过数组过滤条件找到的第一个匹配的元素值的文档将被更新

使用示例
        > db.students.insertMany([
                { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] },
                { "_id" : 2, "semester" : 1, "grades" : [ 90, 90, 92 ] },
                { "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] },
                { "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] },
                { "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] },
                { "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }])  

        使用样式:
                db.collection.find( { <array>: <value> ... },
                                    { "<array>.$": 1 } )
                db.collection.find( { <array.field>: <value> ...},
                                    { "<array>.$": 1 } )
        更新元素值样式:                                    
                db.collection.update(
                   { <array>: value ... },
                   { <update operator>: { "<array>.$" : value } }
                )                                   

        更新数组内嵌文档样式(使用.$.成员方式)      
                db.collection.update(
                   { <query selector> },
                   { <update operator>: { "array.$.field" : value } }
                )

        更新操作时的占位符$匹配查询文档的第一个元素
        数组字段必须为查询的过滤条件

更新数组元素值

        //下面查询semester值为1,grades为90的文档
        //如下结果,所有包含90的文档都被返回        
        > db.students.find( { semester: 1, grades: { $eq: 90 } })//等价:db.students.find({semester:1,grades:90})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] }
        { "_id" : 2, "semester" : 1, "grades" : [ 90, 90, 92 ] }
        { "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] }

        //下面通过占位符$来过滤数组的结果,也即是只有第一个为90的值才会被显示,其余的元素值不被显示
        > db.students.find( { semester: 1, grades: { $eq: 90 } },{ "grades.$": 1 } )
        { "_id" : 1, "grades" : [ 90 ] }
        { "_id" : 2, "grades" : [ 90 ] } //注意这里显示的是该文档的第一个90
        { "_id" : 3, "grades" : [ 90 ] }

        //下面使用占位符进行更新
        > db.students.update({semester: 1, grades:90},{$set:{"grades.$":95}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })  //提示1个文档被更新

        //如下文档_id为1的数组值被更新为95
        > db.students.find( { semester: 1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ] }
        { "_id" : 2, "semester" : 1, "grades" : [ 90, 90, 92 ] }
        { "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] }

        //下面使用multi:true选项,如下可知,2个匹配文档被更新
        //但是仅仅是第一个元素值被更新(文档_id为2数值值为90的第二个元素未更新)
        > db.students.update({semester: 1, grades:90},{$set:{"grades.$":95}},{multi:true})
        WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })

        > db.students.find( { semester: 1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ] }
        { "_id" : 2, "semester" : 1, "grades" : [ 95, 90, 92 ] }
        { "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 95 ] }

更新数组内嵌文档

        //向集合增加一个文档
        > db.students.insert(
        ... {
        ... _id:7,
        ... grades: [
        ...      { grade: 80, mean: 75, std: 8 },
        ...      { grade: 85, mean: 90, std: 5 },
        ...      { grade: 90, mean: 85, std: 3 }
        ...   ]
        ... })
        WriteResult({ "nInserted" : 1 })

        //如下所示,使用数组名.$.成员名的方式进行更新
        //
        > db.students.update(
        ... { _id: 7, "grades.grade": 85 },
        ... { $set: { "grades.$.std" : 6 } })
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        > db.students.find({"grades.grade":85},{ "grades.$": 1 })
        { "_id" : 7, "grades" : [ { "grade" : 85, "mean" : 90, "std" : 6 } ] }

更新数组内嵌文档(多条件匹配)

        //对于多条件的匹配,使用$elemMatch
        > db.students.update({"_id":7,grades:{$elemMatch:{grade:{$lte:90},mean:{$gt:80}}}},
        ... { $set: { "grades.$.std" : 6 } })
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) //提示一条被更新

        //验证结果,尽管有2个内嵌文档满足查询条件,但是只有第一个被更新
        > db.students.find({"grades.std":6}).pretty()
        {
                "_id" : 7,      // Author: Leshami
                "grades" : [    // Blog  : http://blog.csdn.net/leshami
                        {
                                "grade" : 80,
                                "mean" : 75,
                                "std" : 8
                        },
                        {
                                "grade" : 85,
                                "mean" : 90,
                                "std" : 6
                        },
                        {
                                "grade" : 90,
                                "mean" : 85,
                                "std" : 3
                        }
                ]
        }

2、操作符$addToSet

当数组元素值不存在的时候,将该值添加到数组。否则,什么也不做。
        样式:             
                { $addToSet: { <field1>: <value1>, ... } }

        $addToSet确保没有重复的项添加到数组集合,对于已经存在的重复元素不受影响。
        $addToSet不能保证添加时元素的顺序
        如果<field1>为空,操作失败,如果添加的值是数组,那么整个值将作为一个单个元素被追加

        > db.students.update({"_id":6},{$addToSet:{grades:99}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        > db.students.find({"_id":6})
        { "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96, 99 ] }

        //下面尝试再次添加99,如下提示有匹配,但是没有更新
        > db.students.update({"_id":6},{$addToSet:{grades:99}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })       

        //下面的将grades:[100,101]作为一个整体元素添加到数组
        > db.students.update({"_id":6},{$addToSet:{grades:[100,101]}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        //验证,100,101作为了一个整体,而非单个元素
        > db.students.find({"_id":6})
        { "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96, 99, [ 100, 101 ] ] }      

        //结合$each操作符使用$addToSet
        //$addToSet结合$each,允许$addToSet一次添加多个值到数组
        //如下,我们需要将[96,99,100,101]这几个值添加到数组
        >db.students.update({"_id":6},{$addToSet:{grades:{$each:[96,99,100,101]}}})

        //如下面的查询结果,96,99元素值由于之前已经存在,因此未被添加,而100,101则被添加
        > db.students.update({"_id":6},{$addToSet:{grades:{$each:[96,99,100,101]}}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
        > db.students.find({"_id":6})
        { "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96, 99, [ 100, 101 ], 100, 101 ] }

3、操作符$push

$push添加一个指定的值到数组,如果是嵌套文档,使用.成员方式
        样式:
                { $push: { <field1>: <value1>, ... } } 
        行为:
                如果被更新的文档该数组不存在,那么$push将添加数组字段和值
                如果字段不是一个数组,操作失败
                如果值是数组,那么整个数组作为一个单个元素添加到数组

        $push的修改顺序(参考本小点后面的综合示例)
                将添加的元素更新到数组
                如果指定了排序,那么应用排序
                如果指定了slice,那么切割数组
                存储数组                

        示例:
        //字段不存在时的情形
        > db.students.update({"_id":1},{$push:{score:80}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        //查看添加后的结果,score作为一个数组字段添加到文档
        > db.students.find({"_id":1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ], "score" : [ 80 ] }

        //再次对score字段进行$push
        > db.students.update({"_id":1},{$push:{score:90}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        //查看添加后的结果,由于score数组字段存在,因此为其追加数组元素90
        > db.students.find({"_id":1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ], "score" : [ 80, 90 ] }

        > //$push结合$each,一次向数组push多个元素值,相同的元素值并没有忽略
        > //这里是$push与$addToSet最大的一个差别,一个滤重,一个不滤重
        > db.students.update({"_id":1},{$push:{score:{$each:[80,100,120]}}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
        > db.students.find({"_id":1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ], "score" : [ 80, 90, 80, 100, 120 ] }

        //$push结合$each,$slice,$sort的综合示例
        //首先添加文档到集合
        > db.students.insert({
           "_id" : 8,
           "quizzes" : [
              { "wk": 1, "score" : 10 },
              { "wk": 2, "score" : 8 },
              { "wk": 3, "score" : 5 },
              { "wk": 4, "score" : 6 }
           ]
        })

        //使用如下更新操作
        > db.students.update(
           { _id: 8 },
           {
             $push: {
               quizzes: {   //下面使用$each为数组添加3个元素
                  $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],
                  $sort: { score: -1 },  //基于socre倒叙排列
                  $slice: 3              //仅保留3个元素
               }
             }
           }
        )

        //更新后的结果如下,score,10,8,8被保留,其余的被删除
        > db.students.find({"_id":8}).pretty()
        {
                "_id" : 8,
                "quizzes" : [
                        {
                                "wk" : 1,
                                "score" : 10
                        },
                        {
                                "wk" : 2,
                                "score" : 8
                        },
                        {
                                "wk" : 5,
                                "score" : 8
                        }
                ]
        }

4、操作符$pop

$pop操作符移除数组中的第一个或者最后一个元素(1为最后一个元素,-1为第一个元素)
        如果是数组为嵌套文档,使用.成员方式
        样式: 
                { $pop: { <field>: <-1 | 1>, ... } }

        //查看"_id"值为1的文档             
        > db.students.find({"_id":1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ], "score" : [ 80, 90, 80, 100, 120, 80, 100, 120 ] }

        //移除score最后一个元素
        > db.students.update({"_id":1},{$pop:{score:1}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        > db.students.find({"_id":1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ], "score" : [ 80, 90, 80, 100, 120, 80, 100 ] }

        //移除score第一个元素
        > db.students.update({"_id":1},{$pop:{score:-1}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        > db.students.find({"_id":1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ], "score" : [ 90, 80, 100, 120, 80, 100 ] }

        //移除嵌套数组的最后一个元素
        > db.students.update({"_id":8},{$pop:{quizzes:1}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        > db.students.find({"_id":8})
        { "_id" : 8, "quizzes" : [ { "wk" : 1, "score" : 10 }, { "wk" : 2, "score" : 8 } ] }

5、操作符$pull

$pull操作符从现有数组中移除与指定条件匹配的值或值的所有实例
        样式:
                { $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }
        说明:
                如果指定的<condition>数组元素为内嵌文档时,$pull操作符应用<condition>,类似每个数组元素是集合中的文档一样
                如果指定的<value>去移除数组,$pull仅仅移除满足指定条件的数组元素(精确匹配,包括顺序)
                如果指定的<value>去移除一个文档,$pull仅仅移除字段和值精确匹配的数组元素素(顺序可以不同)

        示例:

        移除所有特定元素值       
                > db.students.find({"_id":6})
                { "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96, 99, [ 100, 101 ], 100, 101 ] }

                //移除单个数组元素值
                > db.students.update({"_id":6},{$pull:{grades:99}})
                WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

                //移除嵌套数组元素值
                > db.students.update({"_id":6},{$pull:{grades:[100,101]}})
                WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

                //验证结果
                > db.students.find({"_id":6})
                { "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96, 100, 101 ] }  

              //下面使用$in来移除所有匹配元素
                > db.students.update({"_id":6},{$pull:{grades:{$in:[95,96]}}})
                WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

                //验证结果
                > db.students.find({"_id":6})
                { "_id" : 6, "semester" : 2, "grades" : [ 90, 100, 101 ] }  

        移除所有匹配的特定条件的数字元素    
                //移除数组grades中大于等于100的元素
                > db.students.update({"_id":6},{$pull:{grades:{$gte:100}}})
                WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

                //如下查询100,101元素值已经不存在了
                > db.students.find({"_id":6})
                { "_id" : 6, "semester" : 2, "grades" : [ 90 ] }

        移除文档型数组项目
                > db.survey.insert([
                {
                   _id: 1,
                   results: [
                      { item: "A", score: 5 },
                      { item: "B", score: 8, comment: "Strongly agree" }
                   ]
                },
                {
                   _id: 2,
                   results: [
                      { item: "C", score: 8, comment: "Strongly agree" },
                      { item: "B", score: 4 }
                   ]
                }])         

                //下面的update操作,移除results数组中嵌套文档score的值为8,item值为B的数值元素
                > db.survey.update(
                  { },
                  { $pull: { results: { score: 8 , item: "B" } } },
                  { multi: true }
                )
                WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 1 })   //2个匹配,1个更新

                > db.survey.find().pretty()
                { "_id" : 1, "results" : [ { "item" : "A", "score" : 5 } ] }
                {
                        "_id" : 2,
                        "results" : [
                                {
                                        "item" : "C",
                                        "score" : 8,
                                        "comment" : "Strongly agree"
                                },
                                {
                                        "item" : "B",
                                        "score" : 4
                                }
                        ]
                }

6、操作符$pullAll

该操作符从一个存在的数组中移除指定值得所有实例(即一次删除多个值)。
        $pull操作符是移除一个指定查询的元素,$pullAll移除匹配列出值得所有元素
        样式:
                { $pullAll: { <field1>: [ <value1>, <value2> ... ], ... } }
        说明:
                当指定的<field>是一个内嵌文档或数组时,使用.成员方式
                如果<value>是一个文档或者数组,$pullAll仅仅精确移除匹配指定<value>数组的元素(顺序要求匹配)

        示例
        > db.students.find({"_id":{$in:[1,5]}})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ], "score" : [ 90, 80, 100, 120, 80, 100 ] }

        > db.students.find({"_id":1})
        { "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 95 ], "score" : [ 90, 80, 80 ] }

        > db.students.find({"_id":5}).pretty()
        {
                "_id" : 5,
                "semester" : 2,
                "grades" : [
                        88,
                        88,
                        92
                ],
                "quizzes" : [
                        {
                                "wk" : 5,
                                "score" : 8
                        },
                        {
                                "wk" : 6,
                                "score" : 7
                        },
                        {
                                "wk" : 7,
                                "score" : 6
                        }
                ]
        }

        > db.students.update({"_id":5},{$pullAll:{"quizzes":[{"wk" : 5,"score" : 8}]}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

        > db.students.update({"_id":5},{$pullAll:{"quizzes":[{"wk" : 7,"score" : 6}]}})
        WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
        > db.students.find({"_id":5}).pretty()
        {
                "_id" : 5,
                "semester" : 2,
                "grades" : [
                        88,
                        88,
                        92
                ],
                "quizzes" : [
                        {
                                "wk" : 6,
                                "score" : 7
                        }
                ]
        }

9 MongoDB——》聚合查询(project、match、limit、skip、unwind、group、sort)

db:当前数据库名
test:当前集合名

test集合中的数据如下图所示:
在这里插入图片描述

1聚合

1、聚合
2、聚合运算符
在这里插入图片描述

二、聚合运算符

1、$project

    修改输入文档的结构
    重命名、增加或删除域
    创建计算结果以及嵌套文档

1) 例:获取test集合的weight字段及name字段(_id显示)

db.test.aggregate(
    { $project : {
        weight: 1 ,
        name : 1 
    }}
 );

在这里插入图片描述
2) 例:获取test集合的weight字段及name字段(_id不显示)

db.test.aggregate(
    { $project : {
         _id : 0 ,
        weight: 1 ,
        name : 1 
    }}
 );

在这里插入图片描述3) 例:使用$add给weight字段的值加10,然后将结果赋值给一个新的字段:newWeight

db.test.aggregate(
    { $project : {
         _id : 0 ,
        name : 1  ,
        weight : 1 ,
        newWeight : { $add:["$weight", 10] }
    }}
 );

在这里插入图片描述4) 例:把weight重命名为newWeight

db.test.aggregate(
    { $project : {
         _id : 0 ,
        name : 1  ,
        weight : 1 ,
        newWeight : "$weight"
    }}
 );

在这里插入图片描述

2、$match

    用于过滤数据,只输出符合条件的文档
    在$match中不能使用$geoNear地理空间操作符及$where表达式操作符

1) 例:获取test集合的weight>=0.5且weight<=1

db.test.aggregate( {
    $match : 
        { weight : 
            { $gte : 0.5, $lte : 1 } 
        }
});

或者

db.test.aggregate([
    {$match : 
        { weight : 
            { $gte : 0.5, $lte : 1 } 
        }
    }
]);

在这里插入图片描述2) 例:获取test集合的weight>=0.5且weight<=1,然后将符合条件的记录送到下一阶段$group管道操作符进行处理

db.test.aggregate([
    {$match : 
        { weight : 
            { $gte : 0.5, $lte : 1 } 
        }
    },
    { $group: 
        { _id: null, 
          count: { $sum: 1 } 
        } 
    }
]);

在这里插入图片描述

3、$group

    将集合中的文档分组,可用于统计结果
    在$match中不能使用$geoNear地理空间操作符及$where表达式操作符

1) 例:获取test集合的weight>=0.5且weight<=1,然后将符合条件的记录送到下一阶段$group管道操作符进行处理
在这里插入图片描述

4、$limit

$limit会接受一个数字n,返回结果集中的前n个文档

1) 例:查询5条文档记录

db.test.aggregate({ $limit : 5 });

在这里插入图片描述

5、$skip

$skip接受一个数字n,丢弃结果集中的前n个文档
    限定可以传递到聚合操作的下一个管道中的文档数量

1) 例:获取test集合中第5条数据之后的数据
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值