MongoDB

MongoDB 基础知识

2018-12-01  本文已影响0人  AaronSimon

一、简介

MongoDB 是一个基于分布式 文件存储的NoSQL数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

关系型数据库(SQLite、Oracle、mysql)特点

MongoDB 特点

二、MongoDB 的基本操作

2.1 创建数据库

语法
MongoDB创建数据库的语法格式如下:

use DATABASE_NAME

如果数据库不存在,则指向数据库,但不创建(等待实际数据入库后创建),否则切换到指定的数据库。
示例
创建数据库

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
> use test
switched to db test
> db
test
>

查看当前数据库名称

>db

查看当前db中所有的collection

>show collections

刚创建的数据库 test 并不在数据库的列表中,要显示它,我们需要向 test 数据库插入一些数据

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
> db.message.insert({"name":"simon","msg":"hello"})
2018-12-01T13:38:28.225+0800 E QUERY    [js] SyntaxError: illegal character @(shell):1:18
> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

2.2 删除数据库

语法
MongoDB 删除数据库的语法格式如下:

db.dropDatabase()

删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名
示例
查看所有数据库

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
mytest  0.000GB
> db
mytest
> show  collections
message

删除当前数据库 mytest

> db.dropDatabase()
{ "dropped" : "mytest", "ok" : 1 }

检查数据库列表

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

2.3 创建集合

语法
基本的 createCollection() 命令语法如下:

db.createCollection(name, options)

在命令中, name 是要创建的集合的名称. Options 是一个文档,用于指定配置的集合

参数 类型 描述
Name String 要创建的集合名称
Options Document (可选)指定有关内存大小和索引选项

选项​​参数是可选的,所以只需要到指定的集合名称。以下是可以使用的选项列表:

字段 类型 描述
capped Boolean (可选)如果为true,则启用封顶集合。封顶集合是固定大小的集合,当它达到其最大大小,会自动覆盖最早的条目。如果指定true,则需要也指定size字段。
autoIndexID Boolean (可选)如果为true,自动创建索引_id字段, 默认值是false。
size number (可选)指定集合最大可使用字节。如果封顶如果是 true,那么你还需要指定这个字段。
max number (可选)指定封顶集合允许在文件的最大数量。Size限制优先于此限制。如果一个封顶集合达到大小size限制,未达到文件的最大数量,MongoDB删除旧的文件。如果您更喜欢使用max,确保为上限的集合所需的大小限制,足以包含文档的最大数量。

当插入文档,MongoDB 第一检查大小字段封顶集合,然后它会检查最大的字段。

示例
createCollection() 方法不使用选项的示例如下:

> use mytest
switched to db mytest
> db.createCollection("mycollection")
{ "ok" : 1 }
> show collections
mycollection

createCollection() 方法使用选项的示例如下:

> db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )
{ "ok" : 1 }
> show collections
log
mycollection

可以不需要创建集合。当插入一些文档自动创建的集合。

2.4 删除集合

语法
drop() 命令的基本语法如下

db.COLLECTION_NAME.drop()

示例
现在删除集合名称为 mycollection

> show collections
log
mycollection
> db.mycollection.drop()
true
> show collections
log

drop() 方法将返回 true,如果选择成功收集被丢弃,否则将返回 false

2.5 插入文档

要插入数据到 MongoDB 集合,需要使用 MongoDB 的 insert() 或 save() 方法
语法
insert() 命令的基本语法如下:

db.COLLECTION_NAME.insert(document)

save() 命令的基本语法如下:

db.COLLECTION_NAME.save(document)

示例
执行下面的命令插入文档

db.mycol.insert(
  [
    {
       title: 'MongoDB Overview',
       description: 'MongoDB is no sql database',
       by: 'tutorials itcast',
       url: 'http://www.itcast.cn',
       tags: ['mongodb', 'database', 'NoSQL'],
       likes: 100
    },
    {
       title: 'MySQL Overview',
       description: 'MySQL is sql database',
       by: 'tutorials itcast',
       url: 'http://www.itcast.cn',
       tags: ['MySQL', 'database', 'SQL'],
       likes: 40
    }
  ]
)

插入文档中,如果我们不指定_id参数,然后MongoDB 本文档分配一个唯一的ObjectId。

> db.mycol.find().pretty()
{
        "_id" : ObjectId("5c022988c6e6fc84a60212c1"),
        "title" : "MongoDB Overview",
        "description" : "MongoDB is no sql database",
        "by" : "tutorials itcast",
        "url" : "http://www.itcast.cn",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}
{
        "_id" : ObjectId("5c0229c7c6e6fc84a60212c2"),
        "title" : "MongoDB Overview",
        "description" : "MongoDB is no sql database",
        "by" : "tutorials itcast",
        "url" : "http://www.itcast.cn",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}

_id 是12个字节的十六进制数,唯一一个集合中的每个文档。 12个字节被划分如下:

_id: ObjectId(4 bytes timestamp, 3 bytes machine id, 2 bytes process id, 3 bytes incrementer)

2.6 查询文档

语法
基本的find()方法语法如下:

db.COLLECTION_NAME.find()

示例

> db.mycol.find().pretty()
{
        "_id" : ObjectId("5c022988c6e6fc84a60212c1"),
        "title" : "MongoDB Overview",
        "description" : "MongoDB is no sql database",
        "by" : "tutorials itcast",
        "url" : "http://www.itcast.cn",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}
{
        "_id" : ObjectId("5c0229c7c6e6fc84a60212c2"),
        "title" : "MongoDB Overview",
        "description" : "MongoDB is no sql database",
        "by" : "tutorials itcast",
        "url" : "http://www.itcast.cn",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 100
}

结果显示在一个格式化的方式,可以使用 pretty() 方法。

操作 语法 例子
Equality `{<key>:<value>}`` db.mycol.find({"by":"tutorials itcast"}).pretty()
Less Than {<key>:{$lt:<value>}} db.mycol.find({"likes":{$lt:50}}).pretty()
Less Than Equals {<key>:{$lte:<value>}} db.mycol.find({"likes":{$lte:50}}).pretty()
Greater Than {<key>:{$gt:<value>}} db.mycol.find({"likes":{$gt:50}}).pretty()
Greater Than Equals {<key>:{$gte:<value>}} db.mycol.find({"likes":{$gte:50}}).pretty()
Not Equals {<key>:{$ne:<value>}} db.mycol.find({"likes":{$ne:50}}).pretty()

AND 在MongoDB中用法:

语法
在 find() 方法,如果通过多个键分离',',那么 MongoDB 处理 AND 条件。AND 基本语法如下所示:

db.mycol.find({key1:value1, key2:value2}).pretty()

示例

> db.mycol.find({"by":"tutorials itcast","title": "MongoDB Overview"}).pretty()
{
  "_id" : ObjectId("5799c3eb235910620b89c674"),
  "title" : "MongoDB Overview",
  "description" : "MongoDB is no sql database",
  "by" : "tutorials itcast",
  "url" : "http://www.itcast.cn",
  "tags" : [
    "mongodb",
    "database",
    "NoSQL"
  ],
  "likes" : 100
}
>

对于上面给出的例子相当于where子句 where by='tutorials itcast' AND title='MongoDB Overview',可以通过任意数量的键值对在 find 子句。

OR 在MongoDB的用法

语法

OR条件的基础上要查询文件,需要使用$or关键字。OR 基本语法如下所示:

>db.mycol.find(
   {
      $or: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()

示例

下面给出的例子将显示所有的教程,标题是“MongoDB Overview'或'MySQL Overview'

>db.mycol.find({
  $or: [
    {
      "title": "MySQL Overview"
    },
    {
      "title": "MongoDB Overview"
    }
  ]
}).pretty()
{
  "_id" : ObjectId("57cefded600d5bb1e2acdb70"),
  "title" : "MongoDB Overview",
  "description" : "MongoDB is no sql database",
  "by" : "tutorials itcast",
  "url" : "http://www.itcast.cn",
  "tags" : [
    "mongodb",
    "database",
    "NoSQL"
  ],
  "likes" : 100
}
{
  "_id" : ObjectId("57cefdf7600d5bb1e2acdb71"),
  "title" : "MySQL Overview",
  "description" : "MySQL is sql database",
  "by" : "tutorials itcast",
  "url" : "http://www.itcast.cn",
  "tags" : [
    "MySQL",
    "database",
    "SQL"
  ],
  "likes" : 40
}
>

AND 和 OR 一起使用
示例
面给出的例子将显示 喜爱数高于50,其标题是MongoDB Overview或者是itcast所写 。等效于 SQL where子句 为 where likes>10 AND (by = 'itcast' OR title = 'MongoDB Overview')

db.mycol.find({
  "likes": {
    $gt: 50
  },
  $or: [
    {
      "by": "tutorials itcast"
    },
    {
      "title": "MongoDB Overview"
    }
  ]
}).pretty()
{
  "_id" : ObjectId("57cefded600d5bb1e2acdb70"),
  "title" : "MongoDB Overview",
  "description" : "MongoDB is no sql database",
  "by" : "tutorials itcast",
  "url" : "http://www.itcast.cn",
  "tags" : [
    "mongodb",
    "database",
    "NoSQL"
  ],
  "likes" : 100
}
>

2.7 更新文档

MongoDB 使用 update() 和 save() 方法来更新集合中的文档。接下来让我们详细来看下两个函数的应用及其区别。

2.7.1 update() 更新文档

语法
update() 方法的基本语法如下:

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

参数说明:

示例
下面的例子将设置标题MongoDB Overview的文件,更新其标题是New MongoDB Tutorial

> db.mycol.update({
  'title': 'MongoDB Overview'
},
{
  $set: {
    'title': 'New MongoDB Tutorial'
  }
})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.mycol.find().pretty()
{
    "_id" : ObjectId("5799c3eb235910620b89c674"),
    "title" : "New MongoDB Tutorial",
    "description" : "MongoDB is no sql database",
    "by" : "tutorials itcast",
    "url" : "http://www.itcast.cn",
    "tags" : [
        "mongodb",
        "database",
        "NoSQL"
    ],
    "likes" : 100
}
{
    "_id" : ObjectId("5799c3f3235910620b89c675"),
    "title" : "MySQL Overview",
    "description" : "MySQL is sql database",
    "by" : "tutorials itcast",
    "url" : "http://www.itcast.cn",
    "tags" : [
        "MySQL",
        "database",
        "SQL"
    ],
    "likes" : 40
}

MongoDB默认将只更新单一的文件,来更新多个你需要设置参数置multi为true

>db.mycol.update({'by':'tutorials itcast'},{$set:{'by':'itcast'}},{multi:true})

2.7.2 save() 更新文档

save() 方法覆盖原有的文档 或者 插入新的文档
语法
MongoDB 的 save() 方法的基本语法如下:

db.collection.save(
   <document>,
   {
     writeConcern: <document>
   }
)

参数说明:
document : 要存储的文档数据。
writeConcern :可选,抛出异常的级别。
例子
下面的例子将取代文件具有_id为 '5799c3eb235910620b89c674'

>db.mycol.save(
   {
      "_id" : ObjectId("5799c3eb235910620b89c674"),
       "title":"itcast New Topic",
       "by":"itcast"
   }
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.mycol.find().pretty()
{
    "_id" : ObjectId("5799c3eb235910620b89c674"),
    "title" : "itcast New Topic",
    "by" : "itcast"
}
{
    "_id" : ObjectId("5799c3f3235910620b89c675"),
    "title" : "MySQL Overview",
    "description" : "MySQL is sql database",
    "by" : "tutorials itcast",
    "url" : "http://www.itcast.cn",
    "tags" : [
        "MySQL",
        "database",
        "SQL"
    ],
    "likes" : 40
}}
>

2.8 删除文档

语法
MongoDB 删除文档的函数是remove()

db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

参数说明:

例子
考虑以下数据myLimit集合:

> db.myLimit.insert(
  [
    { "_id" : 0 },
    { "_id" : 1 },
    { "_id" : 2 },
    { "_id" : 3 },
    { "_id" : 4 }
 ]
)
> db.myLimit.find()
{ "_id" : 0 }
{ "_id" : 1 }
{ "_id" : 2 }
{ "_id" : 3 }
{ "_id" : 4 }

下面的例子将删除所有的文档,其_id 是 3

> db.myLimit.remove({"_id" : 3})
WriteResult({ "nRemoved" : 1 })
> db.myLimit.find()
{ "_id" : 0 }
{ "_id" : 1 }
{ "_id" : 2 }
{ "_id" : 4 }

如果有多个记录且要删除的只有第一条记录,那么设置remove()方法中justOne参数设置1或者是true

>db.myLimit.remove({"_id" : {$gt:0}},1)
WriteResult({ "nRemoved" : 1 })

如果不指定删除条件,然后MongoDB将从集合中删除整个文档。这相当于SQL的truncate命令。

> db.myLimit.remove({})
WriteResult({ "nRemoved" : 3 })

2.8 索引

索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文档并选取那些符合查询条件的记录,花费的时间会很多
语法
ensureIndex()方法基本语法格式如下所示:

db.COLLECTION_NAME.ensureIndex({KEY:1})

语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,-1即为降序。

MongoDB 提供了一个 explain 命令让我们获知系统如何处理查询请求。利用 explain 命令,可以很好地观察系统如何使用索引来加快检索,同时可以针对性优化索引。
示例
1. 插入测试数据

db.inventory.insert([
{ "_id" : 1, "item" : "f1", type: "food", quantity: 500 },
{ "_id" : 2, "item" : "f2", type: "food", quantity: 100 },
{ "_id" : 3, "item" : "p1", type: "paper", quantity: 200 },
{ "_id" : 4, "item" : "p2", type: "paper", quantity: 150 },
{ "_id" : 5, "item" : "f3", type: "food", quantity: 300 },
{ "_id" : 6, "item" : "t1", type: "toys", quantity: 500 },
{ "_id" : 7, "item" : "a1", type: "apparel", quantity: 250 },
{ "_id" : 8, "item" : "a2", type: "apparel", quantity: 400 },
{ "_id" : 9, "item" : "t2", type: "toys", quantity: 50 },
{ "_id" : 10, "item" : "f4", type: "food", quantity: 75 }])

2. 无索引查询

db.inventory.find(
   {
      quantity: {
          $gte: 100,
          $lte: 200
      }
  }
).explain("executionStats")
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "mytest.inventory",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "$and" : [
                                {
                                        "quantity" : {
                                                "$lte" : 200
                                        }
                                },
                                {
                                        "quantity" : {
                                                "$gte" : 100
                                        }
                                }
                        ]
                },
                "winningPlan" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "$and" : [
                                        {
                                                "quantity" : {
                                                        "$lte" : 200
                                                }
                                        },
                                        {
                                                "quantity" : {
                                                        "$gte" : 100
                                                }
                                        }
                                ]
                        },
                        "direction" : "forward"
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 3,
                "executionTimeMillis" : 48,
                "totalKeysExamined" : 0,
                "totalDocsExamined" : 10,
                "executionStages" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "$and" : [
                                        {
                                                "quantity" : {
                                                        "$lte" : 200
                                                }
                                        },
                                        {
                                                "quantity" : {
                                                        "$gte" : 100
                                                }
                                        }
                                ]
                        },
                        "nReturned" : 3,
                        "executionTimeMillisEstimate" : 28,
                        "works" : 12,
                        "advanced" : 3,
                        "needTime" : 8,
                        "needYield" : 0,
                        "saveState" : 1,
                        "restoreState" : 1,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "direction" : "forward",
                        "docsExamined" : 10
                }
        },
        "serverInfo" : {
                "host" : "DESKTOP-GVTQ3ND",
                "port" : 27017,
                "version" : "4.0.4",
                "gitVersion" : "f288a3bdf201007f3693c58e140056adf8b04839"
        },
        "ok" : 1
}

从上面三个信息中得出,docsExamined 10条数据,最终才返回nReturned 3条,说明做了7条数据scan的无用功,那么这个时候问题就来了!
3. 创建索引
在quality字段之上添加索引,如下:

db.inventory.createIndex({ quantity: 1})
db.inventory.find(
   { quantity: { $gte: 100, $lte: 200 } }
).explain("executionStats")

结果如下:

db.inventory.find(    { quantity: { $gte: 100, $lte: 200 } } ).explain("executionStats")
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "mytest.inventory",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "$and" : [
                                {
                                        "quantity" : {
                                                "$lte" : 200
                                        }
                                },
                                {
                                        "quantity" : {
                                                "$gte" : 100
                                        }
                                }
                        ]
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "quantity" : 1
                                },
                                "indexName" : "quantity_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "quantity" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "quantity" : [
                                                "[100.0, 200.0]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 3,
                "executionTimeMillis" : 0,
                "totalKeysExamined" : 3,
                "totalDocsExamined" : 3,
                "executionStages" : {
                        "stage" : "FETCH",
                        "nReturned" : 3,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 4,
                        "advanced" : 3,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "docsExamined" : 3,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 3,
                                "executionTimeMillisEstimate" : 0,
                                "works" : 4,
                                "advanced" : 3,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 0,
                                "restoreState" : 0,
                                "isEOF" : 1,
                                "invalidates" : 0,
                                "keyPattern" : {
                                        "quantity" : 1
                                },
                                "indexName" : "quantity_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "quantity" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "quantity" : [
                                                "[100.0, 200.0]"
                                        ]
                                },
                                "keysExamined" : 3,
                                "seeks" : 1,
                                "dupsTested" : 0,
                                "dupsDropped" : 0,
                                "seenInvalidated" : 0
                        }
                }
        },
        "serverInfo" : {
                "host" : "DESKTOP-GVTQ3ND",
                "port" : 27017,
                "version" : "4.0.4",
                "gitVersion" : "f288a3bdf201007f3693c58e140056adf8b04839"
        },
        "ok" : 1
}

当我们执行完createindex之后,再次explain,4个重要的parameters参数就出来了:

4. 查看索引

db.inventory.getIndexes()

三、数据类型

MongoDB 支持如下数据类型:

上一篇下一篇

猜你喜欢

热点阅读