前言

本文从讲解了 MongoDB 的数据导入导出,以及 CRUD 操作。

数据下载:

JSON示例数据:(美国马萨诸塞州邮政代码->点击下载)。

{
    "_id" : "01001",		#序号
    "city" : "AGAWAM",		#城市
    "loc" : [ 			#坐标
        -72.622739, 
        42.070206
    ],
    "pop" : 15338,		#标记
    "state" : "MA"		#州缩写
}

其他 JSON 数据下载:http://jsonstudio.com/resources/

MongoDB - 导入数据:

简介:

mongoimport工具从由其他第三方导出工具创建或可能的[扩展JSON],CSV或TSV导出导入内容`mongoexport。

mongoimport是以系统命令行运行,而不是MongoShell。

操作:

json 导入:

示例代码:

mongoimport --db jsonar --collection zips --file /Users/Desktop/zips.json
  • –db:数据库名称
  • –collection:集合名称
  • –file:文件路径

csv导入:

示例代码:

mongoimport --db users --collection contacts --type csv --headerline --file /opt/backups/contacts.csv
  • –type: 文件类型

注意事项:

mongoimport支持UTF-8编码的数据文件。使用其他编码会产生错误。

Reference:https://docs.mongodb.com/manual/reference/program/mongoimport/index.html

MongoDB - 导出数据:

简介:

mongoexport 是一个实用程序,可以生成一个JSON或CSV导出存储在MongoDB实例中的数据。

mongoimport是以系统命令行运行,而不是MongoShell。

操作:

json导出:

mongoexport --db jsonar --collection zips --out ~/Desktop/zips.json

csv导出:

mongoexport --db jsonar --collection zips --out ~/Desktop/zips.csv

–out 参数指定了导出的文件类型以及文件路径,更多导出方式请参考官方文档。

Reference:https://docs.mongodb.com/manual/reference/program/mongoexport/index.html

MongoDB - 插入文档:

在向 MongoDB 数据库中执行插入操作的时候,如果集合(collection)不存在,插入操作会自动创建一个集合**(当然,MongoDB 也提供了db.createCollection("emp");方法来创建集合)**,存储于集合中的每一个文档都需要一个唯一的_id字段作为 primary_key。如果一个插入文档操作遗漏了_id 字段,MongoDB驱动会自动为_id字段生成一个 [ObjectId],这种情况同样适用于带有参数的 [upsert: true]的 update 操作。

MongoDB主要提供了以下三个方法向集合插入文档:

  • db.collection.insertOne()
  • db.collection.insertMany()
  • db.collection.insert()

insertOne:

db.collection.insertOne()将单个文档插入到集合中。

示例代码:

db.inventory.insertOne(
...    { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
... )

运行结果:

{
	"acknowledged" : true,
	"insertedId" : ObjectId("59eee499cbb5fc46080e6d87")
}

insertOne() 返回一个结果文档,该结果文档中列举了插入文档的_id 字段值为ObjectId("59eee499cbb5fc46080e6d87")

insertMany:

db.collection.insertMany()可以将多个文档插入到集合中。

示例代码:

db.inventory.insertMany([
...    { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
...    { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
...    { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
... ])

运行结果:

{
	"acknowledged" : true,
	"insertedIds" : [
		ObjectId("59eeeb7dcbb5fc46080e6d89"),
		ObjectId("59eeeb7dcbb5fc46080e6d8a"),
		ObjectId("59eeeb7dcbb5fc46080e6d8b")
	]
}

insertMany() 返回包含新插入的文档_id字段值的文档。

insert:

db.collection.insert() 将单个文档或多个文档插入到集合中。

插入单个文档:

示例代码:

db.products.insert( { item: "card", qty: 15 } )

运行结果:

WriteResult({ "nInserted" : 1 })

插入多个文档:

示例代码:

db.products.insert(
   [
     { _id: 11, item: "pencil", qty: 50, type: "no.2" },
     { item: "pen", qty: 20 },
     { item: "eraser", qty: 25 }
   ]
)

运行结果:

BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 3,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})

MongoDB - 读取文档:

MongoDB 提供了 db.collection.find() 方法从集合中读取文档。此方法返回一个游标,要访问文档,需要迭代游标。但是,在MongoShell中,如果返回的游标未使用var关键字分配给变量,那么光标自动迭代最多20次,打印到结果中的前20个文档。(可以使用 DBQuery.shellBatchSize 来改变迭代次数的默认值 20。)

要查询集合中的所有文档,需要将空文档作为查询过滤器参数传递给find方法。

基础查询:

查询 zips 集合中的全部数据,示例代码:

db.zips.find({});

运行结果:

{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" }
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51565, 42.377017 ], "pop" : 36963, "state" : "MA" }
{ "_id" : "01005", "city" : "BARRE", "loc" : [ -72.108354, 42.409698 ], "pop" : 4546, "state" : "MA" }
{ "_id" : "01007", "city" : "BELCHERTOWN", "loc" : [ -72.410953, 42.275103 ], "pop" : 10579, "state" : "MA" }
{ "_id" : "01008", "city" : "BLANDFORD", "loc" : [ -72.936114, 42.182949 ], "pop" : 1240, "state" : "MA" }

如果觉得返回结果太乱,可以使用.pretty()来格式化显示。

查询时也可以指定不需要显示的字段,示例代码:

db.zips.find({},{"loc":0})

运行结果:

/* 1 */
{
    "_id" : "01001",
    "city" : "AGAWAM",
    "pop" : 15338,
    "state" : "MA"
}

/* 2 */
{
    "_id" : "01002",
    "city" : "CUSHMAN",
    "pop" : 36963,
    "state" : "MA"
}

/* 3 */
{
    "_id" : "01005",
    "city" : "BARRE",
    "pop" : 4546,
    "state" : "MA"
}

对于设置的显示字段严格来讲就称为数据的投影操作,如果不需要显示的字段设置“0”,而需要显示的字段设置“1”。

查询时也可以指定相等条件,语法db.集合名称.find({查询条件} [,{设置显示的字段}]

示例代码:

db.inventory.find( { city: "SPRINGFIELD" } )

运行结果:

/* 1 */
{
    "_id" : "01103",
    "city" : "SPRINGFIELD",
    "loc" : [ 
        -72.588735, 
        42.1029
    ],
    "pop" : 2323,
    "state" : "MA"
}

/* 2 */
{
    "_id" : "01104",
    "city" : "SPRINGFIELD",
    "loc" : [ 
        -72.577769, 
        42.128848
    ],
    "pop" : 22115,
    "state" : "MA"
}

/* 3 */
{
    "_id" : "01105",
    "city" : "SPRINGFIELD",
    "loc" : [ 
        -72.578312, 
        42.099931
    ],
    "pop" : 14970,
    "state" : "MA"
}

关系运算:

在MongoDB里面支持的关系查询操作:大于($gt)、小于($lt)、大于等于($gte)、小于等于($lte)、不等于($ne)、等于(key:value、$eq)。

查询pop大于20000的数据:

$gt:

db.zips.find({pop:{$gt:20000}})

$lt:

查询pop小于1000的数据 :

db.zips.find({pop:{$lt:1000}})

$gte:

查询pop 大于等于90000的数据:

db.zips.find({pop:{$gte:90000}})

$lte:

查询 pop 小于等于10的数据:

db.zips.find({pop:{$lte:10}})

$ne:

查询 pop 不等于100的数据:

db.zips.find({pop:{$ne:100}})

$eq:

查询 pop 等于100的数据:

db.zips.find({pop:{$eq:100}})

逻辑运算:

逻辑运算主要就是三种类型:与($and)、或($or)、非($not、$nor)。

$and:

查询 pop为等于10000和city 存在的数据(显式$and查询):

db.zips.find({$and:[{pop:{$ne:10000}},{city:{$exists:true}}]})

查询pop值再10000 - 20000之间的数据(隐式$and查询):

db.zips.find({pop:{$gte:10000,$lte:20000}})

$or:

查询city 为SPRINGFIELD或者pop 大于10000的数据:

db.zips.find({$or:[{city:"SPRINGFIELD"},{pop:{$gte:10000}}]})

$nor:

查询city 不为SPRINGFIELD或者 pop 小于10000的数据(进行或的取反操作):

db.zips.find({$nor:[{city:"SPRINGFIELD"},{pop:{$gte:10000}}]})

求模运算:

$mod:

求模运算使用“$mod”来完成,语法“{$mod : [数字,余数]}”。

db.zips.find({pop:{$mod:[100,10]}})

范围查询:

“$in”(在范围之中)、“$nin”(不在范围之中)

$in:

查询 city 为AGAWAM、CUSHMAN、SPRINGFIELD三个值的数据:

db.zips.find({city:{$in:["AGAWAM","CUSHMAN","SPRINGFIELD"]}})

$nin:

查询 city 中不含AGAWAM、CUSHMAN、SPRINGFIELD三个值的数据:

db.zips.find({city:{$nin:["AGAWAM","CUSHMAN","SPRINGFIELD"]}})

数组查询:

MongoDB中,需要针对于数组数据查询操作,可以使用几个运算符:$all、$size、$slice、$elemMatch。

$all:

查询loc 有42.070206的数据:

db.zips.find({loc:{$all:[42.070206]}})

虽然“$all”计算可以用于数组上,但是也可以用于一个数据的匹配上。

查询loc 有-72.108354和42.409698的数据:

db.zips.find({loc:{$all:[-72.108354,42.409698]}})

$size:

查询 loc中字段数量为2的数据:

db.zips.find({loc:{$size:2}})

$slice:

查询 loc中city为SPRINGFIELD并且字段数量为2的数据:

db.zips.find({city:"SPRINGFIELD"},{loc:{$slice:1}})

查询 loc中city为SPRINGFIELD的数据数据跳过第一条数据返回两条数据:

db.zips.find({city:"SPRINGFIELD"},{loc:{$slice:[1,2]}})

下标查询:

查询 loc中数组的第二个字段,值为42.070206的数据:

db.zips.find({"loc.1":42.070206})

既然在集合里面现在保存的是数组信息,那么数组就可以利用索引操作,使用“key.index”的方式来定义索引。

条件过滤:

$where:

查询 pop 值小于10的数据:

db.zips.find({$where:"this.pop < 10"});

查询 pop 值小于10的数据和id大于10000的值:

db.zips.find({"$and":[{"$where":"this.pop < 10"},{"$where":"this._id > 10000"}]})

正则匹配:

在 MongoDB 中,如果想模糊查询,那就要使用正则表达式来匹配,而且正则表达式使用的是语言Perl兼容的正则表达式的形式。如果要想实现正则使用,则按照如下的定义格式:

·基础语法:{key : 正则标记};

·完整语法:{key : {“$regex” : 正则标记 , “$options” : 选项}}。

指令 释义 语法
i 忽略字母大小写
m 在每行的开始或结尾匹配具有多行值的字符串(多行查找)
x 空白字符串除了被转义的或在字符类中意外的完全被忽略 需要$ regex与$ options语法
s 匹配所有的字符(圆点、“.”),包括换行内容。 需要$ regex与$ options语法

查询 state中以 K 开头的数据(^):

db.zips.find({state:/^K/})

查询 state中包含 k 的数据(不区分大小写):

db.zips.find({state:/k/i})
db.zips.find({state:{$regex:/K/i}})

两种写法均可实现。

数据排序:

MongoDB中数据的排序操作使用“sort()”函数,在进行排序的时候可以有两个顺序:升序(1)、降序(-1)。

查询 pop 数据进行升序排序:

db.zips.find({}).sort({pop:1})

查询 id 数据进行降序排序:

db.zips.find({}).sort({_id:-1})

数据分页:

  • skip(n):表示跨过多少数据行;
  • limit(n):取出的数据行的个数限制。

查询从0开始每页显示10条数据根据 id升序排序:

db.zips.find({}).skip(0).limit(10).sort({"_id":1})

db.zips.find({}).skip(10).limit(10).sort({"_id":1})

其他查询:

$exists:

查询 pop 的值存在且不含1000-5000之间的数据:

db.zips.find( { pop: { $exists: true, $nin: [ 1000, 5000 ] } } )

MongoDB - 更新文档:

在MongoDB中,对于数据的更新操作提供了两类函数:save()、update()。

方法名称 使用介绍
db.collection.updateOne() 即使可能有多个文档通过过滤条件匹配到,但是也最多也只更新一个文档。
db.collection.updateMany() 更新所有通过过滤条件匹配到的文档
db.collection.replaceOne() 即使可能有多个文档通过过滤条件匹配到,但是也最多也只替换一个文档。
db.collection.update() 即使可能有多个文档通过过滤条件匹配到,但是也最多也只更新或者替换一个文档。

默认情况下db.collection.update()只更新一个文档。要更新多个文档,请使用 multi 选项。

修改器:

$set:

$set用来指定一个键的值

$unset:

$unset用来将键完全删除

$inc:

用于,增加和减少:
1、键不存在时创建一个键
2、增加已有键的值
对于分析数据、因果关系、投票或者其他变化数值的地方,使用这个非常方便。

save:

save() 方法通过传入的文档来替换已有文档.

示例代码:

db.zips.save({
    "_id" : "01001",
    "city" : "AGAWAM",
    "loc" : [ 
        -72.622739, 
        42.070206
    ],
    "pop" : 15338,
    "state" : "ZHN"
})

运行结果:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

update:

语法:

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

upsert:布尔值可选。如果设置为true,则在没有文档与查询条件匹配时创建新文档。默认值为false,在找不到匹配项时不插入新文档。

示例代码:

db.zips.update({ _id: 01001},{"city":"ShenZhen","state":"ZHN"},{upsert: true})

运行结果:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

updateOne:

语法:

db.collection.updateOne(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>
   }
)

示例代码:

db.zips.updateOne({"_id":"01002"},{$set:{state:"CHN"}})

运行结果:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

updateMany:

语法:

db.collection.updateMany(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>
   }
)

参数说明:

参数 类型 详解
filter document 更新的选择条件,与find()方法中的查询选择器使用方式相同,可以 指定一个空文档{}来更新集合中的所有文档。
update document 使用更新操作符,如$ set,$ unset或$ rename。 使用update()模式的更改参数的值:value引发错误。
upsert boolean 可选参数。当为true时,updateMany() 如果没有文档与过滤器匹配,则创建新文档。 更新与过滤器匹配的文档。 为了避免多个提前插入,请确保过滤器字段被唯一索引。 默认为false。
writeConcern document 可选参数。描述MongoDB对独立mongod或复制集合或分片集群的写操作所请求的确认级别,省略使用默认的写入关注。
collation document 可选参数。 指定要用于操作的排序规则。 排序规则允许用户指定用于字符串比较的特定于语言的规则,例如字母和重音符号的规则。

示例代码:

db.zips.updateMany({  "state" : "CHN" },{ $set: { pop: "1000"}},{upsert:true});

运行结果:

{"acknowledged" : true,  "matchedCount" : 1.0,  "modifiedCount" : 0.0}

replaceOne:

语法:

db.collection.replaceOne(
   <filter>,
   <replacement>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>
   }
)

示例代码:

db.zips.replaceOne({  "state" : "CHN" },{ "pop" : 0, "state" : "CHINA"});

运行结果:

{"acknowledged" : true,"matchedCount" : 1.0,"modifiedCount" : 1.0}

MongoDB - 删除文档:

MongoDB提供以下方法来删除集合的文档:

方法 说明
db.collection.deleteOne() 最多删除与指定过滤器匹配的单个文档,即使多个文档可能与指定的过滤器匹配。
db.collection.deleteMany() 删除与指定过滤器匹配的所有文档。
db.collection.remove() 删除单个文档或与指定过滤器匹配的所有文档。

deleteOne:

语法:

db.collection.deleteOne(
   <filter>,
   {
      writeConcern: <document>,
      collation: <document>
   }
)

选项说明:

  • filter:类型为 document;使用查询运算符指定删除条件,指定一个空文档{}删除集合中返回的第一个文档。
  • writeConcern:类型为document;可选参数;描述MongoDB对独立mongod或复制集合或分片集群的写操作所请求的确认级别,省略使用默认的写入关注。
  • collation:类型为document;可选参数;指定要用于操作的排序规则。 排序规则允许用户指定用于字符串比较的特定于语言的规则,例如字母和重音符号的规则。

示例代码:

db.zips.deleteOne({state:"CHINA"},{})

运行结果:

{"acknowledged" : true,"deletedCount" : 1.0}

deleteMany:

语法:

db.collection.deleteMany(
   <filter>,
   {
      writeConcern: <document>,
      collation: <document>
   }
)

删除所有符合 state:"MA"的数据:

db.zips.deleteMany({state:"MA"},{})

运行结果:

{"acknowledged" : true,"deletedCount" : 472.0}

删除所有符合state中以R开头的数据(不区分大小写):

db.zips.deleteMany({state:/^R/i},{})

运行结果:

{"acknowledged" : true,"deletedCount" : 70.0}

remove:

romeve函数有两个选项:

  • 删除条件:满足条件的数据被删除;
  • 是否只删除一个数据,如果设置为true或者是1表示只删除一个。

语法:

db.collection.remove(
   <query>,
   <justOne>
)

选项说明:

  • query:类型为document;使用查询运算符指定删除条件,需要清空集合,可以指定为{}
  • justOne:类型为document;可选参数;要将删除限制为只有一个文档,请设置为true。省略使用默认值false并删除符合删除条件的所有文档。

删除 pop 小于2000的数据:

db.zips.remove({pop:{$lt:2000}})

运行结果:

Removed 12436 record(s) in 180ms

删除 city 为MASON的数据,只删除一个:

db.zips.remove({city:"MASON"},{justOne:true})

运行结果:

Removed 1 record(s) in 1ms

删除_id 中带有9的数据:

db.zips.remove({_id:/9/})

运行结果:

Removed 5255 record(s) in 91ms

清空集合zips中的所有内容:

db.zips.remove({})

运行结果:

Removed 11235 record(s) in 136ms

删除zips 集合:

db.zips.drop()

运行结果:

true

参考资料:

查询运算符:https://docs.mongodb.com/manual/reference/operator/query/

MongoDB-CRUD:https://docs.mongodb.com/manual/crud/

MongoDB-writeConcern:https://docs.mongodb.com/manual/reference/write-concern/