MongoDB概览

来源:互联网 发布:java 物联网 开源框架 编辑:程序博客网 时间:2024/05/21 06:45

简介

MongoDB是首先是一种NoSQL(not only SQL)数据库,即非关系数据库。NoSQL有很多种,我们介绍的MongoDB属于文档数据库。 与传统的MySQL,Oracle等关系数据库比,MongoDB在分布式的大规模数据存储上有一定优势。本文介绍了MongoDB的一些基本用法,并在最后介绍其python的接口。

使用

Windows下,在官网下载安装包后,可直接安装。
安装完成后我们开始建立一个简单的数据库。我们新建一个文件夹MyDB,在此文件夹下建立3个子文件夹conf, data, log
在conf文件夹下,我们新建数据库的配置文件mongo.ini,指定数据库的端口,存放数据的路径以及日志的路径。(简单起见,本文暂不介绍数据库权限)

port = 11111dbpath = E:\MongoDB\MyDB\datalogpath = E:\MongoDB\MyDB\log\mongo.log

然后我们使用命令mongod -f mongo.ini启动服务器。(注意环境变量的配置)

服务器启动之后可以在相应的data文件夹和log文件夹中看到生成的数据文件和日志文件。

之后使用命令mongo 127.0.0.1:11111可连接到数据库。这里由于没有启用权限控制,因此有一些Warning.

MongoDB shell version v3.4.3connecting to: 127.0.0.1:11111MongoDB server version: 3.4.3Server has startup warnings:2017-04-19T12:23:19.801+0800 I CONTROL  [initandlisten]2017-04-19T12:23:19.801+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.2017-04-19T12:23:19.801+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.2017-04-19T12:23:19.801+0800 I CONTROL  [initandlisten]>

基本操作

使用命令show dbs查看当前有哪些数据库

> show dbsadmin     0.000GBlocal     0.000GB

我们现在想创建一个新的数据库learn,可以使用命令use learn,切换到learn数据库。此时learn数据库尚未建立,当我们插入一条数据后,其会自动建立。

插入

现在我们使用insert指令来插入一个文档。

> db.my_collect.insert({key:"value"})WriteResult({ "nInserted" : 1 })

这里涉及到了collection的概念。MongoDB中的collection可以类比为关系数据库中的表(table),一个数据库会有若干个colleciton,每个collection又有若干个文档。其与table的不同在于,collection不需要一个预先设定的模式scheme,其中的每个记录可以有完全不同的项。因为collection不用显示地创建,这里我们直接指定了一个暂时不存在的my_collect,并直接向其插入数据。

MongoDB中的文档格式为BSON,一种非常类似JSON的数据格式,我们每次插入的数据,都需要符合这种格式。这篇文档给出了BSON支持的数据类型的一个简要的说明。

BSON


MongoDB的语法也类似于JavaScript,所以也可以这样使用循环来插入数据。

> for (var i = 0; i < 5; i++) db.my_collect.insert({num1:i,num2:5-i})


查询

现在我们来看看得到的结果。

> show collectionsmy_collect> db.my_collect.find(){ "_id" : ObjectId("58f6fe526512d30086571807"), "key" : "value" }{ "_id" : ObjectId("58f6fe686512d30086571808"), "num1" : 0, "num2" : 5 }{ "_id" : ObjectId("58f6fe686512d30086571809"), "num1" : 1, "num2" : 4 }{ "_id" : ObjectId("58f6fe686512d3008657180a"), "num1" : 2, "num2" : 3 }{ "_id" : ObjectId("58f6fe686512d3008657180b"), "num1" : 3, "num2" : 2 }{ "_id" : ObjectId("58f6fe686512d3008657180c"), "num1" : 4, "num2" : 1 }

使用show collections查看数据库中的collections,然后使用find指令,查询collection中的数据。find指令可以指定查询的条件,这里我们没有指定则返回所有的数据。

可以注意到,对每个文档,都有一个_id项,这是MongoDB自动生成的ID,可以确保全数据库中唯一。其具体的意义,参见这里。我们也可以手动指定数据的_id,但一般不推荐这么做。每个文档都需要一个_id项作为主键。

我们接着来看如何进行查询。如前所述,使用find指令可以查询数据,现在我们加上查询条件。

> db.my_collect.find({num1:3}){ "_id" : ObjectId("58f6fe686512d3008657180b"), "num1" : 3, "num2" : 2 }> db.my_collect.find({num1:{$gt:0}, num2:{$lt:3}}){ "_id" : ObjectId("58f6fe686512d3008657180b"), "num1" : 3, "num2" : 2 }{ "_id" : ObjectId("58f6fe686512d3008657180c"), "num1" : 4, "num2" : 1 }

查询的条件需要满足如下的格式

{ <field1>: <value1>, <field2>: <value2>, ... }

观察第二次查询,其查询的是num1比0大,num2比3小的文档。MongoDB使用特殊的运算符$gt,$lt表示大于和小于。

MongoDB的查询条件默认是逻辑与的,也就是当给出的所有条件都满足才会被查到。如果是想使用逻辑或,即所有条件只要满足一条,则需要使用特殊的$or运算符。

> db.my_collect.find({$or:[{num1:{$gt:3}},{key:"value"}]}){ "_id" : ObjectId("58f6fe526512d30086571807"), "key" : "value" }{ "_id" : ObjectId("58f6fe686512d3008657180c"), "num1" : 4, "num2" : 1 }


我们再看一个稍复杂的例子。

> db.my_collect.insert({embbed:{num3:300}, num1:[{"value":100}]})WriteResult({ "nInserted" : 1 })> db.my_collect.find({"embbed.num3":300}){ "_id" : ObjectId("58f706526512d3008657180f"), "embbed" : { "num3" : 300 }, "num1" : [ { "value" : 100 } ] }> db.my_collect.find({"num1.value":100}){ "_id" : ObjectId("58f706526512d3008657180f"), "embbed" : { "num3" : 300 }, "num1" : [ { "value" : 100 } ] }>

我们插入了一个文档。

{     "_id" : ObjectId("58f706526512d3008657180f"),    "embbed" : { "num3" : 300 },    "num1" : [ { "value" : 100 } ]}

我们要查找embbed中的num3为300的项,需要使用"embbed.num3":300来指定,这里使用了.运算符,同时必须使用引号括起来。如果想查询的项放在了数组中,情况类似。


更新

MongoDB中,更新的指令是update,还是先来看一个例子

> db.my_collect.find({key:"value"}){ "_id" : ObjectId("58f6fe526512d30086571807"), "key" : "value" }> db.my_collect.update({key:"value"}, {num1:80})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.my_collect.find({key:"value"})> db.my_collect.find({num1:80}){ "_id" : ObjectId("58f6fe526512d30086571807"), "num1" : 80 }

我们更新了{key:"value"}这个文档,更新之后,_id不变,但是整个文档被替换为了num1:80,原本的key项被覆盖了。

如果我们只是想局部更新而非替换,需使用$set运算符。

> db.my_collect.update({num1:80}, {$set:{num2:97}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.my_collect.find({num1:80}){ "_id" : ObjectId("58f6fe526512d30086571807"), "num1" : 80, "num2" : 97 }

update指令默认指更新查找到的第一个文档,如果想要更新所有文档,需要额外指定第三个参数为{multi:true}.

> db.my_collect.update({num1:{$lt:4}}, {$set:{num2:0}}, {multi:true})WriteResult({ "nMatched" : 4, "nUpserted" : 0, "nModified" : 4 })> db.my_collect.find(){ "_id" : ObjectId("58f6fe526512d30086571807"), "num1" : 80, "num2" : 97 }{ "_id" : ObjectId("58f6fe686512d30086571808"), "num1" : 0, "num2" : 0 }{ "_id" : ObjectId("58f6fe686512d30086571809"), "num1" : 1, "num2" : 0 }{ "_id" : ObjectId("58f6fe686512d3008657180a"), "num1" : 2, "num2" : 0 }{ "_id" : ObjectId("58f6fe686512d3008657180b"), "num1" : 3, "num2" : 0 }{ "_id" : ObjectId("58f6fe686512d3008657180c"), "num1" : 4, "num2" : 1 }{ "_id" : ObjectId("58f706526512d3008657180f"), "embbed" : { "num3" : 300 }, "num1" : [ { "value" : 100 } ] }>


删除

MongoDB中的删除指令是remove. 删除所有条件匹配的文档,如果只想删除第一个满足条件的文档,需要额外指定第二个参数{justOne:true}.

> db.my_collect.remove({num2:0}, {justOne:true})WriteResult({ "nRemoved" : 1 })> db.my_collect.find({num2:0}){ "_id" : ObjectId("58f6fe686512d30086571809"), "num1" : 1, "num2" : 0 }{ "_id" : ObjectId("58f6fe686512d3008657180a"), "num1" : 2, "num2" : 0 }{ "_id" : ObjectId("58f6fe686512d3008657180b"), "num1" : 3, "num2" : 0 }> db.my_collect.remove({num2:0})WriteResult({ "nRemoved" : 3 })> db.my_collect.find({num2:0})>

如果想删除整个collection,可以使用drop指令

> db.my_collect.drop()true> show collections>


索引

索引可以加速查询,我们会对经常查找的项建立索引。首先,我们可以使用getIndexes查看已有的索引。

> db.my_collect.getIndexes()[        {                "v" : 2,                "key" : {                        "_id" : 1                },                "name" : "_id_",                "ns" : "learn.my_collect"        }]

MongoDB会自动给_id项建立索引。我们也可以用指令createIndex方法建立自己的索引。

> db.my_collect.drop()true> for (var i = 1; i < 100; i++) db.my_collect.insert({x:i, y:0})WriteResult({ "nInserted" : 1 })> db.my_collect.createIndex({x:1}){        "createdCollectionAutomatically" : false,        "numIndexesBefore" : 1,        "numIndexesAfter" : 2,        "ok" : 1}> db.my_collect.getIndexes()[        {                "v" : 2,                "key" : {                        "_id" : 1                },                "name" : "_id_",                "ns" : "learn.my_collect"        },        {                "v" : 2,                "key" : {                        "x" : 1                },                "name" : "x_1",                "ns" : "learn.my_collect"        }]>


Python接口

使用命令pip install pymongo安装MongoDB的Python驱动。

我们使用下面的代码来说明pymongo的用法。

#-*- coding=utf-8 -*-from pymongo import MongoClientclient = MongoClient("mongodb://127.0.0.1:11111")  #建立连接db = client['learn']         #数据库db['pytest'].drop()coll = db['pytest'] #collection# 插入文档,返回结果包括_idfor i in range(100):    coll.insert_one(        {            "x" : i,            "y" : i%10,        }        )#查找y=9的文档并打印cursor = coll.find({"$or":[{"x":{"$lt":3}}, {"y":9}]}) # x<3 or y==9for doc in cursor:    print(doc)#更新coll.update_many({"x":{"$lt":6}}, {"$set":{"z":2}}) # x < 6 ==> z=2coll.update_one({"x":{"$lt":6}}, {"$set":{"z":1}})  # x < 6 --> z=1cursor = coll.find({"x":{"$lt":6}}) # x < 6for doc in cursor:    print(doc)#删除coll.delete_many({"x":{"$gt":5}}) # x > 5cursor = coll.find()for doc in cursor:    print(doc)


See also:

  1. https://docs.mongodb.com/getting-started/shell/
  2. https://docs.mongodb.com/getting-started/python/
0 0