MongoDB 学习笔记3 - 命令行操作示例

1. 背景

本节使用命令行操作 mongDB。

2.知识

MongoDB是一个文档型数据库,它将数据存储在类似json的文档中。

特点:

  • 数据以JSON方式存储,处理数据最自然,支持数组和嵌套对象。
  • 查询也以JSON方式,支持筛选和排序,聚合。

和 关系型数据的概念对照表:

MongoDB 传统的关系型数据库
database database, 相同
collections table
documents row
fields columns
Indexes Indexes 相同
Cursors -

总结:MongoDB 可以每行数据的结构都不同,支持非结构化数据。 区别于 传统的严格结构化数据。

MongoDB 适用场景

单一解决方案还是多技术方案?
对于许多项目来说 - 或者说大多数 - 单一解决案是一个明智的选择。只有你自己才知道,引进新技术是否利大于弊。引入MongoDB 往往不会完全替换旧的方案(比如用Mongo替换MySQL),而是说“不用再依赖单一的解决案来处理你的数据”,作为数据存储的局部替代方案,是对你现有数据存储方案能力的局部增强。

比如说用 Lucene 作为关系型数据库的全文检索索引的加强,或者用 Redis 作为持久型 key-value 存储对缓存存储的增强,MongoDB 就是用来保存你的数据能力的处理增强。

3. 使用 Docker 安装 mongoDB

(1) 安装 mongoDB

我使用 docker 安装,编写一个 docker-compose.yml 文件:

version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456

(2) 启动docker容器

在当前文件夹下执行:

docker compose up -d

(3) 进入容器 内

docker exec -it mongodb_mongo_1 /bin/bash

(4) 进入 mongodb 的命令行交互界面

执行:

mongo

或者 指定用户名和密码登录:

mongo --host localhost --authenticationDatabase "admin" -u "root" -p'123456'

也可使用其他客户端工具,比如 navcat for mongoDB

下面展示一些使用 mongoShell 的示例。

4. 基本操作

进入命令行后就可以使用 mongodb 的语句了, 比如 输入 db.version() 查看mongoDB 的版本号。

查看版本号
执行: db.version()

> db.version()
4.2.5

记得按下 tab 键帮忙快速输入
使用<Tab>键来自动完成

查看有哪些数据库
执行:show dbs

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

切换数据库:
执行:use 数据库名

> use admin

查看这个数据库下有哪些用户
执行:: show users

> show users
{
    "_id" : "admin.root",
    "userId" : UUID("997d937e-d05f-4df0-b233-e3f549e25bbc"),
    "user" : "root",
    "db" : "admin",
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ],
    "mechanisms" : [
        "SCRAM-SHA-1",
        "SCRAM-SHA-256"
    ]
}

查看当前数据库的状态
执行:: db.stats()

> db.stats()
{
    "db" : "admin",
    "collections" : 2,
    "views" : 0,
    "objects" : 3,
    "avgObjSize" : 208.66666666666666,
    "dataSize" : 626,
    "storageSize" : 40960,
    "numExtents" : 0,
    "indexes" : 3,
    "indexSize" : 61440,
    "scaleFactor" : 1,
    "fsUsedSize" : 28565065728,
    "fsTotalSize" : 62725623808,
    "ok" : 1
}

要显示您正在使用的数据库,请键入db:

db

创建新的数据库
先切换到不存在的数据库。通过创建集合时,MongoDB会创建数据库。

比如我要建一个名字叫做 new_db 的库,示例:

> use new_db
switched to db new_db
> db.table1.insertOne({x:1})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("60f6e7ad60d17362b807365e")
}

一个名叫 "table1" 的 collection 就被创建了。
然后查看一下 刚刚建的 Collection :

> db.table1.find()
{ "_id" : ObjectId("60f6e7ad60d17362b807365e"), "x" : 1 }

5. 基本的增删改查 CRUD

插入 数据
格式:
db.collection.insertOne() 3.2版中的新功能
db.collection.insertMany() 3.2版中的新功能

“ collection ” 换成你实际的 “表” 名。
示例:

> db.table1.insertOne({name:"zyfvir"})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("60f6e8fe60d17362b807365f")
}

一次插入多条数据
使用 insertMany 方法:

db.inventory.insertMany( [ 
    { item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] },
    { item: "notebook", status: "A",  size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] },
    { item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] },
    { item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] },
    { item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);

下文的一些查询要用到这个结构的文档,它还有size ,instock 两个嵌入的子文档。

读取 collection
格式:db.collection.find()
示例:

> db.table1.find({})
{ "_id" : ObjectId("60f6e7ad60d17362b807365e"), "x" : 1 }
{ "_id" : ObjectId("60f6e8fe60d17362b807365f"), "name" : "zyfvir" }

删除一条数据

> db.table1.deleteOne({"x":1})
{ "acknowledged" : true, "deletedCount" : 1 }

删除数据

> db.table1.remove({"name" : "zyfvir"})
WriteResult({ "nRemoved" : 1 })

查询全部

> db.inventory.find()

指定条件的查询
下面的例子返回inventory集合中状态为“A”的所有文档中的所有字段:

db.inventory.find( { status: "A" } )

该操作对应于以下SQL语句:

SELECT * from inventory WHERE status = "A"

仅返回指定的字段和_id字段

> db.inventory.find( { status: "A" }, { item: 1, status: 1 } )
{ "_id" : ObjectId("60f6f27960d17362b8073660"), "item" : "journal", "status" : "A" }
{ "_id" : ObjectId("60f6f27960d17362b8073661"), "item" : "notebook", "status" : "A" }
{ "_id" : ObjectId("60f6f27960d17362b8073664"), "item" : "postcard", "status" : "A" }

明确表达某个字段不显示
比如:不显示_id 字段

db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )

查询展示 嵌入式文档中的特定字段

db.inventory.find(
  { },
  { "size.uom": 1 }
 )

说明:用 逗号 操作符 size.uom 这样的格式表达子嵌入文档。

查询空字段
先插入示例数据:

db.inventory.insertMany([
   { _id: 1, item: null },
   { _id: 2 }
])

查询匹配包含值是null:
格式:{item:null}
查询匹配包含值是null的item字段或不包含item字段的文档。

db.inventory.find( { item: null } )

类型检查
格式:{item:{$ type:10}}
查询只匹配包含item字段值为null的文档; 即item字段的值为Null(类型编号10):

db.inventory.find( { item : { $type: 10 } } )

更多类型参考:BSON Type

指定AND条件
逗号分隔即可:
以下查询选择嵌套字段h小于15,嵌套字段uom等于“ in”,状态字段等于“ D”的所有文档:

db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

更新集合中的文档
使用 $set 示例:

db.inventory.updateOne(
    { item: "paper" },
    {
        $set: { "size.uom": "cm", status: "P" }, 
        $currentDate: { lastModified: true }
    }
)

更新操作:
使用$set运算符将size.uom字段的值更新为“ cm”,将状态字段的值更新为“ P”,
使用$currentDate运算符将lastModified字段的值更新为当前日期。 如果lastModified字段不存在,则$currentDate将创建该字段。 有关详细信息,请参见$currentDate

更换文档
要替换_id字段以外的文档的全部内容,请将一个全新的文档作为第二个参数传递给db.collection.replaceOne()。

db.inventory.replaceOne(
   { item: "paper" },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)

5. 索引

索引支持在MongoDB中有效地执行查询。如果没有索引,MongoDB必须执行集合扫描,即扫描集合中的每个文档,

默认id索引
在创建集合期间,MongoDB 在_id字段上创建唯一索引。

创建索引
要在Mongo Shell中创建索引 ,请使用 db.collection.createIndex().

以下示例在name字段上创建单个键降序索引:

db.collection.createIndex( { name: -1 } )

复合索引
MongoDB还支持多个字段上的用户定义索引,即 复合索引。

6.参考:

想了解更多 docker 部署 mongoDB 请参考:
https://hub.docker.com/_/mongo?tab=description&page=1&ordering=last_updated

https://github.com/docker/compose

https://docs.mongoing.com/indexes

END

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容