• MongoDB学习笔记,基础+增删改查+索引+聚合...


    基础了解

    对应关系 -> https://docs.mongodb.com/manual/reference/sql-comparison/
    database -> database
    collection -> table
    document -> row //无模式
    field -> column
    --------------------------------------------------------------------------------------
    使用数据库
    use 数据库名称
    
    创建数据库并创建集合myNewCollection1插入数据
    use myNewDB
    db.myNewCollection1.insertOne( { x: 1 } )
    --------------------------------------------------------------------------------------
    创建集合并插入数据
    db.myNewCollection22.insertOne( { xxx: 1 } )
    
    固定大小集合 capped collection 先进先出
    创建一个集合x1 是上限集合,大小200字节 最大2个document,先进先出
    也可以不指定document大小db.createCollection("x1", { capped : true, size : 200} )
    db.createCollection("x1", { capped : true, size : 200, max : 2 } )
    
    检查是否为上限集合 false true
    db.collection.isCapped() 
    
    返回集合有多少document
    db.collection.count() 
    
    转换为上限集合
    db.runCommand({"convertToCapped": "collection", size: 100000});
    
    查看collection并升序转换成数组输出,降序 -1
    printjson(db.collection.find().sort({$natural:1}).toArray())
    
    collection methods ->
    https://docs.mongodb.com/manual/reference/method/js-collection/
    --------------------------------------------------------------------------------------
    BSON Types
    
    插入数据为undefined
    db.collection.insert({x:undefined})
    查找需要
    db.getCollection('a001').find({x:undefined})//错误
    db.getCollection('a001').find({x:{$type:6}})
    db.getCollection('a001').find({x:{$type:"undefined"}})
    
    详情:$type对应Number https://docs.mongodb.com/manual/reference/bson-types/
    
    _id 5d89674154e8289fdac72ea5 十六进制
    
    八位 5d896741 表示时间 十进制 1569285953 北京时间 2019/9/24 8:45:53
    十位 54e8289fda 随机数 十进制 364672229338
    六位 c72ea5 计数器从随机数开始 十进制 13053605
    
    16 -> 10 进制 https://tool.lu/hexconvert/
    时间戳 -> 北京时间 https://tool.chinaz.com/Tools/unixtime.aspx
    

    基本查询操作

    写在一起中间无换行表示同一个效果

    // db.people.insertOne( {//插入并创建表
    //     user_id: "abc123",
    //     age: 55,
    //     status: "A"
    //  } )
    
    // db.people.createIndex( { user_id: 1 } )//创建 增索引
    
    // db.people.createIndex( { user_id: 1, age: -1 } )//创建 增索引 和 减索引
    
    // db.people.drop()//删除表
    
    // db.people.updateMany(//设置列 join_date 内容为当前时间,列没有就添加
    //     { },
    //     { $set: { join_date: new Date() } }
    // )
    
    // db.people.updateMany(//删除所有列 join_date
    //     { },
    //     { $unset: { "join_date": "" } }
    // )
    
    // db.people.insertOne(//插入一条数据
    //    { user_id: "bcd001", age: 45, status: "A" }
    // )
    
    // db.people.find()//查询所有数据
    
    // db.people.find(//只查询三个字段 _id user_id status
    //     { },
    //     { user_id: 1, status: 1 }
    // )
    
    // db.people.find(//只查询两个字段 user_id status
    //     { },
    //     { user_id: 1, status: 1, _id: 0 }
    // )
    
    // db.people.find(//查询状态不等于A
    //     { status: { $ne: "A" } }
    // )
    
    // db.people.find(//查询status="A" AND age=50
    //     { status: "A",
    //       age: 50 }
    // )
    
    // db.people.find(//查询status="A" OR age=50
    //     { $or: [ { status: "A" } , { age: 50 } ] }
    // )
    
    // db.people.find(// >25
    //     { age: { $gt: 25 } }
    // )
        
    //     db.people.find(// <25
    //    { age: { $lt: 25 } }
    // )
       
    //    db.people.find(// >25 <=50
    //    { age: { $gt: 25, $lte: 50 } }
    // )
    
    // db.people.find( { user_id: /abc/ } )// LIKE '%abc%'
    // db.people.find( { user_id: { $regex: /abc/ } } )
    
    // db.people.find( { user_id: /^abc/ } )// LIKE 'abc%'
    // db.people.find( { user_id: { $regex: /^abc/ } } )
    
    // db.people.find( { status: "A" } ).sort( { user_id: 1 } )//ASC
    
    // db.people.find( { status: "A" } ).sort( { user_id: -1 } )//DESC
    
    // db.people.count()// count(*)
    // db.people.find().count()
    
    // db.people.count( { user_id: { $exists: true } } )// 含有user_id的所有count(*)
    // db.people.find( { user_id: { $exists: true } } ).count()
    
    // db.people.count( { age: { $gt: 500 } } )//age>500的count(*)
    // db.people.find( { age: { $gt: 500 } } ).count()
    
    // db.people.aggregate( [ { $group : { _id : "$status" } } ] )//安装status分组,查询别名_id 只查询status
    // db.people.distinct( "status" )//返回一个数组 ["A","B","C","CCCC"]
    
    // db.people.findOne()//查询第一条
    // db.people.find().limit(1)
    
    // db.people.find().limit(5).skip(10)//查询大于第 11 12 13 14 15条,如果没有14 15 就显示 11 12 13
    
    // db.people.updateMany(//更新年龄大于5555的状态设置为CCCC
    //    { age: { $gt: 5555 } },
    //    { $set: { status: "CCCC" } }
    // )
    
    // db.people.updateMany(//更新状态为CCCC的设置
    //    { status: "CCCC" } ,
    //    { $inc: { age: 3 } }
    // )
    
    // db.people.deleteMany( { status: "D" } )//删除状态为D的所有数据
    
    // db.people.deleteMany({})//清空表数据
    

    查询

    查询
    
    比较查询操作符 -> https://docs.mongodb.com/manual/reference/operator/query-comparison/
    
    $eq -> = -> { <field>: { $eq: <value> } }
    
    $ne -> != -> {field: {$ne: value} }
    
    $gt -> > -> { field: { $gt: value} }
    
    $gte -> >= -> { field: { $gte: value} }
    
    $lt -> < -> { field: { $lt: value} }
    
    $lte -> <= -> { field: { $lte: value} }
    
    有一个就可以
    $in -> in -> { field: { $in: [<value1>, <value2>, ... <valueN> ] } }
    
    都没有才可以
    $nin -> not in -> { field: { $nin: [ <value1>, <value2> ... <valueN> ]} }
    --------------------------------------------------------------------------------------
    逻辑查询操作符 -> https://docs.mongodb.com/manual/reference/operator/query-logical/
    
    第一个false 余下不执行
    $and -> and -> { $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
    
    $or -> or -> { $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
    
    对or的结果取反
    $nor -> not or -> { $nor: [ { <expression1> }, { <expression2> }, ...  { <expressionN> } ] }
    
    对符合的结果取反
    $not -> not -> { field: { $not: { <operator-expression> } } }
    --------------------------------------------------------------------------------------
    元素查询操作符 -> https://docs.mongodb.com/manual/reference/operator/query-element/
    
    $exists -> exists -> { field: { $exists: true/false } }
    
    $type -> { field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
    // { field: { $type: "string" } }
    // { field: { $type: ["string","int"] } }
    --------------------------------------------------------------------------------------
    评估查询操作符 -> https://docs.mongodb.com/manual/reference/operator/query-evaluation/
    
    // 根据表达式来匹配数据
    $expr -> { $expr: { <expression> } }
    
    // 根据schema来匹配 required必须含有,properties属性,bsonType类型
    $jsonSchema -> { $jsonSchema: <JSON Schema object> }
    
    这里匹配 如果field=0,1,2,3,4,5 v1=2 v2=1 表示除2余1的数,所以是1 3 5
    $mod -> { field: { $mod: [ v1, v2 ] } }
    
    匹配正则表达式
    {filed:{$regex:/a/}} -> 只要含有a,区分大小写
    {filed:{$regex:/^a/}} -> 第一个字母是a,区分大小写
    $regex -> 通常用 方式3
    { <field>: { $regex: /pattern/, $options: '<options>' } }//方式1
    { <field>: { $regex: 'pattern', $options: '<options>' } }//方式2
    { <field>: { $regex: /pattern/<options> } }//方式3
    
    全文检索,不支持中文,根据索引进行匹配,
    $text -> 例如 { $text: { $search: "coffee" } } 查找含有coffee的
    
    非常强大 支持js
    $where
    例如
    db.x.find({
        $where:function(){
            return this.item=="ijk123"&&this.qty==3 //this表示document(行)
        }
    })
    --------------------------------------------------------------------------------------
    数组查询操作符 -> https://docs.mongodb.com/manual/reference/operator/query-array/
    
    必须所有的值都要有,$in则表示只有一个就可以
    $all -> { <field>: { $all: [ <value1> , <value2> ... ] } }
    
    只要匹配一个满足就可以
    $elemMatch -> { <field>: { $elemMatch: { <query1>, <query2>, ... } } }
    例如:
    { results: { $elemMatch: { $gte: 80, $lt: 85 } } }
    { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } }
    
    根据数组大小匹配
    $size -> 
    匹配数组大小为2的,两个效果相同
    { field: { $size: 2 } }
    {$where:function(){return this.field.length==2}}
    

    更新

    更新
    
    db.collection.update({},{$set:{"a":1}})更新第一条
    db.collection.updateMany({},{$set:{"a":1}})更新全部
    
    自动更新操作符 -> https://docs.mongodb.com/manual/reference/operator/update-field/
    $inc -> { $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }
    {},{$inc:{"age":1,"c":-2,"h.g":2}}//age+1 c-2 h.g+2 字段不存在会创建0+数值
    
    $mul -> { $mul: { <field1>: <number1>, ... } }
    {},{$mul:{"age":5,"h":-1}}//age*5 h*(-1) 数值也可为小数,字段不存在会创建为0*数值
    
    新值最小 就更新
    $min -> { $min: { <field1>: <value1>, ... } }
    
    新值最大 就更新
    $max -> { $max: { <field1>: <value1>, ... } }
    
    $rename -> {$rename: { <field1>: <newName1>, <field2>: <newName2>, ... } }
    {},{$rename:{"age":"age1","my.doc":"c.h"}}//更新字段 age -> age1 my.doc -> c.h
    
    $set -> { $set: { <field1>: <value1>, ... } }
    //如果不存在_id:1 不会做任何反应,如果存在,则会字段重新赋值,不存在的字段会添加
    {_id:1},{$set:{"a":1,"h.g":2}}
    
    $unset -> { $unset: { <field1>: "", ... } }
    {},{$unset:{"a":""}}//字段a后面设置"" 这里就删除了字段a,不论a是什么类型
    
    $setOnInsert ->
    db.collection.update(
       <query>,
       { $setOnInsert: { <field1>: <value1>, ... } },
       { upsert: true }
    )
    
    例如:
    db.collection.update(//collection为空 会插入一个文档,并且设置一条 _id:1 c1:apple c2:100
      { _id: 1 },
      {
         $set: { c1: "apple" },
         $setOnInsert: { c2: 100 }
      },
      { upsert: true }
    )
    
    $currentDate -> { $currentDate: { <field1>: <typeSpecification1>, ... } }
    也可以把 date 换成 timestamp 字符戳
    {},{$currentDate:{mydate:{$type:"date"}}}
    

    数组

    数组
    
    $ -> { "<array>.$" : value }
    可以作为占位符 表示一个 //_id=1 grades=80的把 grade.$ 改为999 只能改一条,改第一个
       { _id: 1, grades: 80 },
       { $set: { "grades.$" : 999 } }
    { "_id" : 1, "grades" : [ 85, 80, 80 ] } -> { "_id" : 1, "grades" : [ 85, 999, 80 ] }   
    
    $[] -> { <update operator>: { "<array>.$[]" : value } }
    可以做占位符 表示全部
    {_id:1},{$inc:{"sz.$[]":3}}
    {_id:1,sz:[1,2,3]} -> {_id:1,sz:[4,5,6]}
    
    $[diy] -> 这里的diy可以随便改 就是一个标识符
    {},{$set:{"sz.$[x]":777}},{arrayFilters:[{"$[x]":{$eq:3}}]}
    {"_id:1","sz":[3,5,3]}
    {"_id:2","sz":[3,3,8]}
    
    {"_id:1","sz":[777,5,777]},
    {"_id:2","sz":[777,777,8]}
    
    $addToSet -> { $addToSet: { <field1>: <value1>, ... } }
    将元素添加数组
    {_id:1},{$addToSet:{"sz":"3"}} ->{"sz":["1","2"]} ->{"sz":["1","2","3"]}
    {_id:1},{$addToSet:{"sz":["4","5"]}} ->{"sz":["1","2"]} ->{"sz":["1","2",["4","5"]]}
    
    $pop -> { $pop: { <field>: <-1 | 1>, ... } }
    {_id:1},{$pop:{"sz":-1}}//移除数组第一个
    {_id:1},{$pop:{"sz":1}}//移除数组最后一个
    
    $pull -> { $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }
    字段后面跟条件 
     { _id: 1 }, { $pull: { scores: {$in:[0,5]} } }//自定义删除所有 0和5
      { _id: 1 }, { $pull: { scores: {$gt:7} } }//删除大于7的
    
    $pullAll -> { $pullAll: { <field1>: [ <value1>, <value2> ... ], ... } }
    删除数组所有的 0 和 5
     { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } }
     
    $push -> { $push: { <field1>: <value1>, ... } }
    {_id:1},{$push:{"sz":3}} -> {"sz":[1,2]} -> {"sz":[1,2,3]}//单个添加
    {_id:1},{$push:{"sz":[4,5]}} -> {"sz":[1,2]} -> {"sz":[1,2,[4,5]]}//整体添加单个数组
    {_id:1},{$push:{"sz":{$each:[4,5]}}} -> [1,2] -> [1,2,4,5]//批量添加
    {_id:1},{$push:{"sz":{$each:[],$sort:1}}} -> [2,1,3] -> [1,2,3]//数组排序 1升序 -1降序
    {_id:1},{$push:{"sz":{$each:[8,2],$sort:1}}} -> [2,1,3] -> [1,2,,2,3,8]//添加+排序
    {_id:1},{$push:{"sz":{$each:[5,6],$sort:1,$slice:3}}}
    原数据 -> 添加 -> 排序(1升序 -1降序) -> 截取(3前三条 -3后三条)
    [2,1,3] -> [2,1,3,5,6] ->[1,2,3,5,6] ->[1,2,3]
    
    $each
    { $addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
    { $push: { <field>: { $each: [ <value1>, <value2> ... ] } } }
    
    {_id:1},{$addToSet:{"sz":{$each:[4,5]}}}// [2,1] -> [2,1,4,5]
    {_id:1},{$push:{"sz":{$each:[4,5]}}}// [2,1] -> [2,1,4,5]
    
    $slice 截取 -> 配合$push $each一起使用
    {_id:1},{$push:{"sz":{$each:[8,6],$slice:3}}}
    [1,2] -> [1,2,8]// 3前三条 -3后三条 0清空数组
    
    $sort 排序 -> 配合$push $each一起使用
    {_id:1},{$push:{"sz":{$each:[8,6],$sort:1}}}
    [1,2] -> [1,2,6,8]// 1升序 -1降序
    
    $position 插入位置 -> 配合$push $each一起使用
    {_id:1},{$push:{"sz":{$each:[9],$position:1}}}
    [3,5,8] -> [3,1,5,8]
    1表示在第一个元素后面追加 0表示在开头添加 大于元素个数表示在最后追加
    

    增删改查

    增删改查
    
    insert
    db.collection.insertOne({})//插入一条
    db.collection.insertOne({})//插入第一条
    db.collection.insertMany([{},{}])//插入多条
    db.collection.insert({})//插入一条
    db.collection.insert({},{})//插入第一条
    db.collection.insert([{},{}])//插入多条
    
    delete
    db.collection.deleteOne({"a":1})//删除a为1的第一条
    db.collection.deleteMany({"a":1})//删除a为1的全部
    db.collection.deleteMany({})//清空collection
    db.collection.remove()
    {"a":1}//删除a为1的全部
    {"a":1},{justOne:true}//删除a为1的第一条
    
    update
    db.collection.updateOne({"a":1},{$set:{"a":2}})//更新第一条
    db.collection.updateOne({"a":1},{$set:{"a":2}})//更新全部
    db.collection.replaceOne({"a":1},{"b":2,"c":3})//替换第一条的数据
    
    find
    db.collection.findOne({"a":1})//查询符合条件的第一条数据
    db.collection.find({})//查询collection全部数据
    db.collection.findOneAndDelete({"a":1})//查询正常返回第一条并且删除
    db.collection.findOneAndReplace({"a":1},{"c":2,"d":3})//查询正常返回第一条并且替换
    //查询正常返回第一条并更新,字段不存在就添加
    db.collection.findOneAndUpdate({"d":"dd"},{$set:{"e":"ee"}})
    
    bulk 支持以下方法,一个出错,不影响其他的
    insertOne
    updateOne
    updateMany
    replaceOne
    deleteOne
    deleteMany
    
    try {
       db.characters.bulkWrite(
          [
             { insertOne :
                {
                   "document" :
                   {
                      "_id" : 4, "char" : "Dithras", "class" : "barbarian", "lvl" : 4
                   }
                }
             },
             { insertOne :
                {
                   "document" :
                   {
                      "_id" : 5, "char" : "Taeln", "class" : "fighter", "lvl" : 3
                   }
                }
             },
             { updateOne :
                {
                   "filter" : { "char" : "Eldon" },
                   "update" : { $set : { "status" : "Critical Injury" } }
                }
             },
             { deleteOne :
                { "filter" : { "char" : "Brisbane"} }
             },
             { replaceOne :
                {
                   "filter" : { "char" : "Meldane" },
                   "replacement" : { "char" : "Tanys", "class" : "oracle", "lvl" : 4 }
                }
             }
          ]
       );
    }
    catch (e) {
       print(e);
    }
    

    索引创建

    索引创建
    
    Single Index 单键索引
    db.collection.createIndex({"a":1})//a非数组 1升序索引 -1降序索引
    
    Compound Index 复合索引
    db.collection.createIndex( { "a": 1, "b": 1 } )
    
    Multikey Index 多键值索引
    db.collection.createIndex({"a":1})//这里的a是一个数组
    db.collection.createIndex({"a":1,"b":1})//a数组 b非数组 创建复合索引
    
    Text Indexes 全文索引,不支持中文
    db.collection.createIndex( { "a": "text" } )
    
    Hashed Indexes 哈希索引
    db.collection.createIndex( { "_id": "hashed" } )
    
    Unique Indexes 唯一索引
    插入数据不可以重复
    db.collection.createIndex( { "a": 1 }, { unique: true } )
    
    Partial Indexes 局部索引
    db.users.createIndex(//年龄>=21才能给username加升序索引,唯一索引
       { username: 1 },
       { unique: true, partialFilterExpression: { age: { $gte: 21 } } }
    )
    
    Sparse Indexes 稀疏索引
    db.collection.createIndex({"a":1},{sparse:true})//对a建立索引
    
    TTL Indexes 过期索引*重要,可做定时过期
    1,只支持单个索引,复合索引不支持
    2,类型要为 BSON 日期 或 含有 BSON 日期的数组
    3,expireAfterSeconds 单位秒,正的 或 0 ,如果为0 在指定日期时到期
    4,如果是数组,最小的那个时间到期就会删除
    5,不含有该索引字段 或 字段不是日期类型,不会过期
    6,_id 不能设置 TTL索引
    7,时间到期后不会立马删除,后台60s执行一次
    
    只能设置一个字段,单位秒
    db.collection.createIndex({"a":1},{expireAfterSeconds:65})
    

    索引管理

    索引管理
    
    //插入自定义时间
    db.test.insert({'time':ISODate("2012-11-02 07:58:51")})
    
    查看
    	表的全部索引
    	db.collection.getIndexes()
    	
    	索引字段名
    	db.collection.getIndexKeys()
    
    	数据库全部索引
    	db.getCollectionNames().forEach(function(collection) {
    	   indexes = db[collection].getIndexes();
    	   print("Indexes for " + collection + ":");
    	   printjson(indexes);
    	});
    
    删除
    	删除b升序索引 -1删除降序索引
    	db.collection.dropIndex({"b":1})
    
    	删除全部索引
    	db.collection.dropIndexes()
    	
    修改
        删除再创建
    

    GridFS 分布式文件系统

    GridFS 分布式文件系统
    
    1,多机器储存备份
    2,可以突破一般文件的限制,可以大于16M
    3,分段存储,不是整个存储
    
    mongofiles -> https://docs.mongodb.com/manual/reference/program/mongofiles/
    
    默认localhost:27017
    --host
    
    默认27017
    --port
    
    指定数据库
    --db
    
    前缀 默认fs
    --prefix
    ....
    ...
    ...
    

    聚合管道

    聚合管道 Aggregation Pipeline Stages -> https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/
    
    db.collection.aggregate([{},{},...,{}])//一个{}表示一个管道
    1,$addFields
    2,$bucket
    3,$bucketAuto
    4,$collStats
    5,$count
    
    			aggregate([//查询字段score>80的总数,假设有3条记录 返回{"passing_scores":3}
    				{
    				  $match: {
    					score: {$gt: 80}
    				  }
    				},
    				{
    				  $count: "passing_scores"
    				}
    			]);
    
    6,$facet
    7,$geoNear
    8,$graphLookup
    9,$group
    
    		{
    		  $group:
    			{
    			  _id: null或者$字段
    			  <field1>: { <accumulator1> : <expression1> },
    			  ...
    			}
    		}
    
    		$sum 相加
    			对字段price*quantity的结果相加得到总价格
    			totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }
    		$avg 平均值
    			邱quantity字段平均值
    			averageQuantity: { $avg: "$quantity" }
    		$first 第一个值
    		$last 最后一个值
    		$min 最小值
    		$max 最大值
    		$push 对结果
    			对author分组,每个作者的标题String放入books数组
    			{ $group : { _id : "$author", books: { $push: "$title" } } }
    
    									aggregate( [//不分组 计算document数量
    									  {
    										$group: {
    										   _id: null,
    										   count: { $sum: 1 }
    										}
    									  }
    									] );
    
    									{ "_id" : null, "count" : 8 }
    									---
    									aggregate( [ { $group : { _id : "$item" } } ] );//按照item字段分组
    
    									{ "_id" : "abc" }
    									{ "_id" : "jkl" }
    									{ "_id" : "def" }
    									{ "_id" : "xyz" }
    									---
    									aggregate(
    									  [
    										// First Stage
    										{
    										  $group :
    											{
    											  _id : "$item",
    											  totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }
    											}
    										 },
    										 // Second Stage
    										 {
    										   $match: { "totalSaleAmount": { $gte: 100 } }
    										 }
    									   ]
    									 )
    									//先按照item分组,对字段price*quantity的结果相加得到总价格,如果总价格>=100就显示
    									---
    									$group : {
    										   _id : null,
    										   totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } },
    										   averageQuantity: { $avg: "$quantity" },
    										   count: { $sum: 1 }
    										}
    									计算所有行的总销售额,所有行的quantity平均值,所有行的数量
    
    10,$indexStats
    11,$limit
    
    		aggregate(//取5条数据
    			{ $limit : 5 }
    		);
    
    12,$listSessions
    13,$lookup 表关联
    
    			aggregate([
    			   {
    				 $lookup:
    				   {
    					 from: "表2",
    					 localField: "表1字段",
    					 foreignField: "表2字段",
    					 as: "表1添加列名,类型数组,放匹配表2的document"
    				   }
    			  },
    			  {$match:{"_id":1}}//对结果再进行匹配 _id:1
    			]);
    			// localField String -> foreignField String
    			// localField String[] -> foreignField String
    
    14,$match -> { $match: { <query> } }
    
    			aggregate(
    				[ { $match : { author : "dave" } } ]
    			);
    
    15,$merge
    16,$out
    
    			aggregate([//把匹配到的结果放入diy的表中,如果已存在则自动清空内容再插入
    				{
    				  $match: {score: {$gt: 80}}
    				},
    				{
    				  $out: "diy"
    				}
    			]);
    
    17,$planCacheStats
    18,$project -> 要显示哪些字段
    
    			只显示_id title author字段
    			aggregate( [ { $project : { title : 1 , author : 1 } } ] )
    
    			只显示title author字段
    			aggregate( [ { $project : { _id: 0, title : 1 , author : 1 } } ] )
    
    			不显示lastModified字段
    			aggregate( [ { $project : { "lastModified": 0 } } ] )
    
    			不显示author.first lastModified字段
    			aggregate( [ { $project : { "author.first" : 0, "lastModified" : 0 } } ] )
    
    			不显示author字段中的first lastModified字段
    			aggregate( [ { $project: { "author": { "first": 0}, "lastModified" : 0 } } ] )
    
    			显示title author.first author.last 
    			并显示字段 author.middle,值不能为"" 或 不存在字段
    			aggregate( [
    			   {
    				  $project: {
    					 title: 1,
    					 "author.first": 1,
    					 "author.last" : 1,
    					 "author.middle": {
    						$cond: {
    						   if: { $eq: [ "", "$author.middle" ] },
    						   then: "$$REMOVE",
    						   else: "$author.middle"
    						}
    					 }
    				  }
    			   }
    			] );
    
    			aggregate( [ { $project: { "stop.title": 1 } } ] )
    			等同于
    			aggregate( [ { $project: { stop: { title: 1 } } } ] )
    
    			aggregate(
    			   [
    				  {
    					 $project: {
    						title: 1,
    						isbn: {
    						   prefix: { $substr: [ "$isbn", 0, 3 ] },//下标 0 1 2
    						   group: { $substr: [ "$isbn", 3, 2 ] },//下标 3 4
    						   publisher: { $substr: [ "$isbn", 5, 4 ] },//下标 5 6 7 8
    						   title: { $substr: [ "$isbn", 9, 3 ] },//下标 9 10 11
    						   checkDigit: { $substr: [ "$isbn", 12, 1] }//下标 12
    						},
    						lastName: "$author.last",//添加新字段
    						copiesSold: "$copies"//添加新字段
    					 }
    				  }
    			   ]
    			)
    
    			数组 例子 { "_id" : 1, "x" : 1, "y" : 1 }
    			aggregate( [ { $project: { myArray: [ "$x", "$y" ] } } ] ) 
    			->{ "_id" : 1, "myArray" : [ 1, 1 ] }
    
    			原字段中无someField,显示null
    			aggregate( [ { $project: { myArray: [ "$x", "$y", "$someField" ] } } ] )
    			-> { "_id" : 1, "myArray" : [ 1, 1, null ] }
    
    19,$redact
    20,$replaceRoot
    21,$replaceWith
    22,$sample
    23,$set
    24,$skip -> { $skip: <positive integer> }
    
    			aggregate(// 不显示前面5条记录
    				{ $skip : 5 }
    			);
    
    25,$sort ->{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
    
    			aggregate([// 1升序 -1降序
    				 { $sort : { age : 1, posts: -1 } }
    			])
    
    26,$sortByCount
    27,$unset
    28,$unwind
    

    十一 mapReduce

    mapReduce 重量级聚合 -> mapReduce -> map -> reduce -> finalize -> out
    
    
    流程图解 -> https://docs.mongodb.com/manual/core/map-reduce/
    使用方法 -> https://docs.mongodb.com/manual/reference/command/mapReduce/
    			db.runCommand({
    							 mapReduce: <collection>,
    							 map: <function>,
    							 reduce: <function>,
    							 finalize: <function>,
    							 out: <output>,
    							 query: <document>,
    							 sort: <document>,
    							 limit: <number>,
    							 scope: <document>,
    							 jsMode: <boolean>,
    							 verbose: <boolean>,
    							 bypassDocumentValidation: <boolean>,
    							 collation: <document>,
    							 writeConcern: <document>
    						 });
    			 
    方法介绍 -> https://docs.mongodb.com/manual/reference/method/db.collection.mapReduce/
    
    			db.collection.mapReduce(
    									 <map>,
    									 <reduce>,
    									 {
    									   out: <collection>,
    									   query: <document>,
    									   sort: <document>,
    									   limit: <number>,
    									   finalize: <function>,
    									   scope: <document>,
    									   jsMode: <boolean>,
    									   verbose: <boolean>,
    									   bypassDocumentValidation: <boolean>
    									 }
    								   )
    								   
    常用四项:
       1,map
    		function(){
    			emit(this.cust_id, this.price);
    		}
    	  发射出去 key-value , 这里 this就是当前的document
       2,reduce
    	   function(key, values) {
    		  return result;//result类型与map类型一致
    	   } 
       3,query  
    		{ age:{ $gte: 18 }}
       4,finalize
    		在reduce后执行
            function(key, reducedValue) {
    			return modifiedObject;
    		}
    					
    
    例1:------------------------------------
    db.a.insert([
        {_id:1,sku_id:1,stock:1},
        {_id:2,sku_id:3,stock:2},
        {_id:3,sku_id:2,stock:3},
        {_id:4,sku_id:1,stock:4},
        {_id:5,sku_id:2,stock:5},
    ])
    
    var diy_map=function(){
           emit(this.sku_id,this.stock)
    }
    
    var diy_reduce=function(k,v){
           return Array.sum(v)
    }
        
    db.runCommand({
        mapReduce:"a",//对应的collection名称
        map:diy_map,
        reduce:diy_reduce,
        out:{inline:1}//在内存中执行
    })
    
    输出
    ---
    /* 1 */
    {
        "results" : [ 
            {
                "_id" : 1.0,
                "value" : 5.0
            }, 
            {
                "_id" : 2.0,
                "value" : 8.0
            }, 
            {
                "_id" : 3.0,
                "value" : 2.0
            }
        ],
        "timeMillis" : 23,
        "counts" : {
            "input" : 5,
            "emit" : 5,
            "reduce" : 2,
            "output" : 3
        },
        "ok" : 1.0
    }
    ---
    
    如果把 return Array.sum(v) 换成 return {"my_k":k,"my_v":v} 则输出
    ---
    /* 1 */
    {
        "results" : [ 
            {
                "_id" : 1.0,
                "value" : {
                    "my_k" : 1.0,
                    "my_v" : [ 
                        1.0, 
                        4.0
                    ]
                }
            }, 
            {
                "_id" : 2.0,
                "value" : {
                    "my_k" : 2.0,
                    "my_v" : [ 
                        3.0, 
                        5.0
                    ]
                }
            }, 
            {
                "_id" : 3.0,
                "value" : 2.0
            }
        ],
        "timeMillis" : 24,
        "counts" : {
            "input" : 5,
            "emit" : 5,
            "reduce" : 2,
            "output" : 3
        },
        "ok" : 1.0
    }
    ---
    如果想把结果输出放入一个collection 把 out:{inline:1} 缓存 out:"diy_document" 输出
    out:{inline:1}输出内容的"result":[{.},{.},{.}]换成 "result":"diy_document"
    ---
    /* 1 */
    {
        "result" : "c",
        "timeMillis" : 40,
        "counts" : {
            "input" : 5,
            "emit" : 5,
            "reduce" : 2,
            "output" : 3
        },
        "ok" : 1.0
    }
    ---
    diy_document内容为 out:{inline:1}输出result字段[]里的内容
    ---
    /* 1 */
    {
        "_id" : 1.0,
        "value" : {
            "my_k" : 1.0,
            "my_v" : [ 
                1.0, 
                4.0
            ]
        }
    }
    
    /* 2 */
    {
        "_id" : 2.0,
        "value" : {
            "my_k" : 2.0,
            "my_v" : [ 
                3.0, 
                5.0
            ]
        }
    }
    
    /* 3 */
    {
        "_id" : 3.0,
        "value" : 2.0
    }
    ---
    
    整合finalize
    
    var diy_map=function(){
           emit(this.sku_id,this.stock)
    }
    
    var diy_reduce=function(k,v){
           return {"my_k":k,"my_v":v};
    }
    
    var diy_finalize=function(k,v){
        v.diy_field="我是在diy_finalize添加的字段"
        return {"my_k2":k,"my_v2":v};
    }
        
    db.runCommand({
        mapReduce:"a",//对应的collection名称
        map:diy_map,
        reduce:diy_reduce,
        finalize:diy_finalize,
        out:{inline:1}//在内存中执行
    })
    
    输出
    ---
    /* 1 */
    {
        "results" : [ 
            {
                "_id" : 1.0,
                "value" : {
                    "my_k2" : 1.0,
                    "my_v2" : {
                        "my_k" : 1.0,
                        "my_v" : [ 
                            1.0, 
                            4.0
                        ],
                        "diy_field" : "我是在diy_finalize添加的字段"
                    }
                }
            }, 
            {
                "_id" : 2.0,
                "value" : {
                    "my_k2" : 2.0,
                    "my_v2" : {
                        "my_k" : 2.0,
                        "my_v" : [ 
                            3.0, 
                            5.0
                        ],
                        "diy_field" : "我是在diy_finalize添加的字段"
                    }
                }
            }, 
            {
                "_id" : 3.0,
                "value" : {
                    "my_k2" : 3.0,
                    "my_v2" : 2.0
                }
            }
        ],
        "timeMillis" : 33,
        "counts" : {
            "input" : 5,
            "emit" : 5,
            "reduce" : 2,
            "output" : 3
        },
        "ok" : 1.0
    }
    ---
    
  • 相关阅读:
    c++中stl函数的使用
    java 中String类的常见方法和StringBuffer类的使用
    c++模板类和模板函数
    c++简单工厂类的设计模式
    Android自定义的button按钮
    c++基类与派生类之间的转换
    Unity和Android结合出现Unabled to convert class into dex format
    jz2240用tftp下载程序步骤
    解决jz2440不能ping同主机问题
    android中的事件传递机制
  • 原文地址:https://www.cnblogs.com/taopanfeng/p/11684889.html
Copyright © 2020-2023  润新知