MongoDB实战读书笔记(一):JavaScript shell操作MongoDB

1 基本增删改查

  • 基本概念:
    • 数据库:同关系型数据库
    • 集合:类似关系型数据库的表
    • 文档:类似关系型数据库的行
    • 字段:类似关系型数据库的列
  • 操作:
    • insert:新增,若新增数据的主键已经存在,则会抛异常提示主键重复,不保存当前数据。
    • save:新增或更新,若新增数据的主键已经存在,则会对当前已经存在的数据进行修改操作。
    • find:查询
    • count:计数
    • update:更新
    • remove:删除文档
    • drop:删除集合
// db.collectionName.insert(document)
db.users.insert({
    username: "smith"
})
db.users.save({
    username: "jones"
})

// db.collectionName.find(query)
db.users.find()
db.users.find({username:"smith"})
db.users.find({
    $and:[
        {username:"smith"},
        {_id:ObjectId("5bac8a98f47a87df04000912")}
    ]
})

db.users.count()

// 更新操作
db.users.update({country:"China"},{$set:{username:"smith"}})

// 替换操作
db.users.update({username:"smith"},{country:"China"})

// 删除字段
db.users.update({username:"smith"},{$unset:{country:1}})

// 修改操作
db.users.update({
    username: "smith"
}, {
    $set: {
        favorites: {
			cities: ["China", "Japan"],
            movies: ["1408", "The String", "Casablanca"]
        }
    }
})

// 添加到容器中
db.users.update({
    "favorites.movies": "Casablanca"
}, {
    	//$push:不保证唯一
        $addToSet: {"favorites.movies":"Te Room"}
    },
		false, // 当文档不存在时,是否插入
		true   // 是否进行多个更新
)

// 删除文档
db.users.remove()

// 删除集合
db.users.drop()

2 索引

// 批量插入
for(var i = 0;i<20000;i++){
	db.numbers.save({num:i});
}

// 范围查询
db.numbers.find({num:{$gte:50,$lt:70}});

db.numbers.find({num:{$gt:50}}).explain("executionStats");
// 无索引结果:
{
    "queryPlanner": {
        "plannerVersion": NumberInt("1"), // 版本
        "namespace": "naladb.numbers", // 库.集合
        "indexFilterSet": false, // 是否有indexFilterSet
        "parsedQuery": { 
            "num": {
                "$gt": 50
            }
        },
        "winningPlan": { //查询优化器针对该query所返回的最优执行计划的详细内容
            "stage": "COLLSCAN", // 最优执行计划的stage
            "filter": { // 过滤条件
                "num": {
                    "$gt": 50
                }
            },
            "direction": "forward" // 查询顺序
        },
        "rejectedPlans": [ ] // 其他执行计划
    },
    "executionStats": {
        "executionSuccess": true, // 执行结果
        "nReturned": NumberInt("87"), // 
        "executionTimeMillis": NumberInt("0"), // 执行时间
        "totalKeysExamined": NumberInt("0"), // 索引扫描条目
        "totalDocsExamined": NumberInt("138"),  // 文档扫描条目
        "executionStages": {
            "stage": "COLLSCAN",
            "filter": {
                "num": {
                    "$gt": 50
                }
            },
            "nReturned": NumberInt("87"), // 返回的条目
            "executionTimeMillisEstimate": NumberInt("0"),
            "works": NumberInt("140"),
            "advanced": NumberInt("87"),
            "needTime": NumberInt("52"),
            "needYield": NumberInt("0"),
            "saveState": NumberInt("1"),
            "restoreState": NumberInt("1"),
            "isEOF": NumberInt("1"),
            "invalidates": NumberInt("0"),
            "direction": "forward",
            "docsExamined": NumberInt("138")
        }
    },
    "serverInfo": {
        "host": "i-t0gpyby1",
        "port": NumberInt("27017"),
        "version": "3.4.5",
        "gitVersion": "520b8f3092c48d934f0cd78ab5f40fe594f96863"
    },
    "ok": 1
}
// 有索引结果
{
    "queryPlanner": {
        "plannerVersion": NumberInt("1"),
        "namespace": "naladb.numbers",
        "indexFilterSet": false,
        "parsedQuery": {
            "$and": [
                {
                    "num": {
                        "$lt": 70
                    }
                },
                {
                    "num": {
                        "$gt": 50
                    }
                }
            ]
        },
        "winningPlan": {
            "stage": "FETCH",
            "inputStage": {
                "stage": "IXSCAN",
                "keyPattern": {
                    "num": 1
                },
                "indexName": "num_1",
                "isMultiKey": false,
                "multiKeyPaths": {
                    "num": [ ]
                },
                "isUnique": false,
                "isSparse": false,
                "isPartial": false,
                "indexVersion": NumberInt("2"),
                "direction": "forward",
                "indexBounds": {
                    "num": [
                        "(50.0, 70.0)"
                    ]
                }
            }
        },
        "rejectedPlans": [ ]
    },
    "executionStats": {
        "executionSuccess": true,
        "nReturned": NumberInt("19"),
        "executionTimeMillis": NumberInt("2"),
        "totalKeysExamined": NumberInt("19"), // 通过索引扫描的个数
        "totalDocsExamined": NumberInt("19"),
        "executionStages": {
            "stage": "FETCH",
            "nReturned": NumberInt("19"),
            "executionTimeMillisEstimate": NumberInt("0"),
            "works": NumberInt("20"),
            "advanced": NumberInt("19"),
            "needTime": NumberInt("0"),
            "needYield": NumberInt("0"),
            "saveState": NumberInt("0"),
            "restoreState": NumberInt("0"),
            "isEOF": NumberInt("1"),
            "invalidates": NumberInt("0"),
            "docsExamined": NumberInt("19"),
            "alreadyHasObj": NumberInt("0"),
            "inputStage": {
                "stage": "IXSCAN",
                "nReturned": NumberInt("19"),
                "executionTimeMillisEstimate": NumberInt("0"),
                "works": NumberInt("20"),
                "advanced": NumberInt("19"),
                "needTime": NumberInt("0"),
                "needYield": NumberInt("0"),
                "saveState": NumberInt("0"),
                "restoreState": NumberInt("0"),
                "isEOF": NumberInt("1"),
                "invalidates": NumberInt("0"),
                "keyPattern": {
                    "num": 1
                },
                "indexName": "num_1", // 使用的索引名
                "isMultiKey": false,
                "multiKeyPaths": {
                    "num": [ ]
                },
                "isUnique": false,
                "isSparse": false,
                "isPartial": false,
                "indexVersion": NumberInt("2"),
                "direction": "forward",
                "indexBounds": {
                    "num": [
                        "(50.0, 70.0)"
                    ]
                },
                "keysExamined": NumberInt("19"), 
                "seeks": NumberInt("1"),
                "dupsTested": NumberInt("0"),
                "dupsDropped": NumberInt("0"),
                "seenInvalidated": NumberInt("0")
            }
        }
    },
    "serverInfo": {
        "host": "i-t0gpyby1",
        "port": NumberInt("27017"),
        "version": "3.4.5",
        "gitVersion": "520b8f3092c48d934f0cd78ab5f40fe594f96863"
    },
    "ok": 1
}
// 参考:https://www.cnblogs.com/c-abc/p/6023824.html

// 创建索引
db.numbers.createIndex({num:1})
// 查看索引
db.numbers.getIndexes()


状态 描述
COLLSCAN 全表扫描
IXSCAN 索引扫描
FETCH 根据索引去检索指定document
SHARD_MERGE 将各个分片返回数据进行merge
SORT 表明在内存中进行了排序
LIMIT 使用limit限制返回数
SKIP 使用skip进行跳过
IDHACK 针对_id进行查询
SHARDING_FILTER 通过mongos对分片数据进行查询
COUNT 利用db.coll.explain().count()之类进行count运算
COUNTSCAN count不使用Index进行count时的stage返回
COUNT_SCAN count使用了Index进行count时的stage返回
SUBPLA 未使用到索引的$or查询的stage返回
TEXT 使用全文索引进行查询时候的stage返回
PROJECTION 限定返回字段时候stage的返回

3 基本管理

// 数据库
show dbs;

// 集合
show collections;

// 数据库信息
db.stats()
db.runCommand({dbstats:1});
// 结果
{
    "db": "test",
    "collections": NumberInt("4"), // 集合数
    "views": NumberInt("0"), 
    "objects": NumberInt("471233"), // 记录数
    "avgObjSize": 179.008626305883, // 每条记录的平均大小
    "dataSize": 84354772, // 记录的总大小
    "storageSize": 30236672, // 预分配的存储空间大小
    "numExtents": NumberInt("0"), // 事件数
    "indexes": NumberInt("9"), //索引数
    "indexSize": 10051584, // 索引大小
    "ok": 1
}

// 集合信息
db.collectionName.stats()
db.runCommand({collstats:"numbers"})
// 结果
{
    "ns": "naladb.numbers",
    "size": NumberInt("700000"), // 大小
    "count": NumberInt("20000"), // 总记录数
    "avgObjSize": NumberInt("35"),
    "storageSize": NumberInt("376832"),
    "capped": false,
    // 参考:https://yq.aliyun.com/articles/255163
    "wiredTiger": {
        ...
    },
    "nindexes": NumberInt("2"),
    "totalIndexSize": NumberInt("454656"),
    "indexSizes": {
        "_id_": NumberInt("221184"), // 索引_id的大小
        "num_1": NumberInt("233472")
    },
    "ok": 1
}
  • 查看mongo shell指令实现
db.runCommand
// 结果
// v3.4.5
function (command) {    
    if (!isString(command) && !isObject(command))        
        nav_throwError("command must be string or object");  
    return this.forwardToCustomFunction("databaseRunCommand", command);
}

// v2.6.10
function ( obj ){
    if ( typeof( obj ) == "string" ){
        var n = {};
        n[obj] = 1;
        obj = n;
    }
    return this.getCollection( "$cmd" ).findOne( obj );
}

db.collectionName.save
// 结果
function (document, options) {
    if (!document)
        nav_throwError("db.collection.save requires document object");

    if (isNumber(document) || isString(document))
        nav_throwError("db.collection.save only accept document object");

    if (isUndefined(document._id)) {
        document._id = new ObjectId();
        return this.insert(document, options);
    } else {
        options = options || {};
        options.upsert = true;
        return this.update({ _id: document._id }, document, options);
    }
}
原文地址:https://www.cnblogs.com/linzhanfly/p/9714260.html