MongoDB

MongoDB

参考网址

https://mongodb.net.cn/manual/tutorial/getting-started/ -中文手册

https://www.runoob.com/mongodb/mongodb-connections.html -菜鸟教程

https://developer.aliyun.com/article/54367 -writeConcern原理解析

https://www.cnblogs.com/shanyou/p/3494854.html - MongoDB 聚合管道

linux下启动MongoDB 指令

查看服务器状态

[root@localhost bin]# systemctl status mongod.service

开机自启动

systemctl enable mongod.service

启动服务

systemctl start mongod.service

数据库

创建数据库

查看当前数据库

> db
test

切换数据库

进入数据库,如果没有会创建,但是插入数据才会再数据库列表中显示

> use examples
switched to db examples

查看所有数据库

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

 

删除数据库

删除数据库

进入数据库,执行:db.dropDatabase()

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
test    0.000GB
​
> use test
switched to db test
​
> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }

 

集合

创建集合

db.createCollection(name, options)

字段类型描述
capped 布尔 (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。 当该值为 true 时,必须指定 size 参数。
size 数值 (可选)为固定集合指定一个最大值,即字节数。 如果 capped 为 true,也需要指定该字段。
max 数值 (可选)指定固定集合中包含文档的最大数量。
db.createCollection("BBB")
{ "ok" : 1 }
​
db.createCollection("bbb",{capped:true,size:5000,max:5000})
{ "ok" : 1 }

查看集合

进入数据库,

> use test
> show collections
AAA
BBB
bbb
ccc

删除集合

> db.ccc.drop()
true
> show collections
AAA
BBB
bbb

 

文档

插入文档

save():如果 _id 主键存在则更新数据,如果不存在就插入数据。该方法新版本中已废弃,可以使用 db.collection.insertOne()db.collection.replaceOne() 来代替。

insert(): 若插入的数据主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常,提示主键重复,不保存当前数据。

db.COLLECTION_NAME.insert(document)
或
db.COLLECTION_NAME.save(document)
或
db.COLLECTION_NAME.insertOne()
或
db.COLLECTION_NAME.insertMany()

insert()

db.collection.insert(
   <document or array of documents>,
   {
     writeConcern: <document>,
     ordered: <boolean>
   }
)
db.collection.insert({         
    "title" : "MongoDB 教程",         
    "description" : "MongoDB 是一个 Nosql 数据库",         
    "by" : "菜鸟教程",         
    "url" : "http://www.runoob.com",         
    "tags" : [                 
        "mongodb",                 
        "database",                 
        "NoSQL"         
    ],         
    "likes" : 100 })

insertOne()

参数说明:

  • document:要写入的文档。

  • writeConcern:写入策略,默认为 1,即要求确认写操作,0 是不要求

w: <number>,数据写入到number个节点才向用客户端确认

  • {w: 0} 对客户端的写入不需要发送任何确认,适用于性能要求高,但不关注正确性的场景

  • {w: 1} 默认的writeConcern,数据写入到Primary就向客户端发送确认

  • {w: "majority"} 数据写入到副本集大多数成员后向客户端发送确认,适用于对数据安全性要求比较高的场景,该选项会降低写入性能

j: <boolean> ,写入操作的journal持久化后才向客户端确认

  • 默认为"{j: false},如果要求Primary写入持久化了才向客户端确认,则指定该选项为true

wtimeout: <millseconds>,写入超时时间,仅w的值大于1时有效。

当指定{w: }时,数据需要成功写入number个节点才算成功,如果写入过程中有节点故障,可能导致这个条件一直不能满足,从而一直不能向客户端发送确认结果,针对这种情况,客户端可设置wtimeout选项来指定超时时间,当写入过程持续超过该时间仍未结束,则认为写入失败

db.collection.insertOne(
   <document>,
   {
      writeConcern: <document>
   }
)
> db.collection.insertOne(
{"name":"wxh","age":23},
{writeConcern:{w:1,j:false,wtimeout:1000}}
)

insertMany()

db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)
db.collection.insertMany([
{"name":"wxh","age":23},
{"smoking":false,"glasses":true}])

 

更新文档

update() 方法

  • query : update的查询条件,类似sql update查询内where后面的。

  • update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的

  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。

  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。

  • writeConcern :可选,抛出异常的级别。

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
> db.collection.find().pretty()
{
    "_id" : ObjectId("6216f6f0bfbdbcab2efdc46f"),
    "title" : "MongoDB 教程",
    "description" : "MongoDB 是一个 Nosql 数据库",
    "by" : "菜鸟教程",
    "url" : "http://www.runoob.com",
    "tags" : [
        "mongodb",
        "database",
        "NoSQL"
    ],
    "likes" : 100
}
​
> db.collection.update(
{"by":"菜鸟教程"},
{$set:{"url":"www.wxh.com"}},
{upsert:false,multi:true,writeConcent:{w:1,j:false,wtimeout:1000}})
​
> db.collection.find().pretty()
{
    "_id" : ObjectId("6216f6f0bfbdbcab2efdc46f"),
    "title" : "MongoDB 教程",
    "description" : "MongoDB 是一个 Nosql 数据库",
    "by" : "菜鸟教程",
    "url" : "www.wxh.com",
    "tags" : [
        "mongodb",
        "database",
        "NoSQL"
    ],
    "likes" : 100
}

 

删除文档

  • query :(可选)删除的文档的条件。

  • justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。

  • writeConcern :(可选)抛出异常的级别。

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

删除部分文档

db.collection.remove( 
    {"title" : "MongoDB 教程"}, 
    { justOne: false } 
)

删除全部文档

 db.collection.remove({})

 

查询文档

MongoDB 与 RDBMS Where 语句比较

操作格式范例RDBMS中的类似语句
等于 {:} db.col.find({"by":"菜鸟教程"}).pretty() where by = '菜鸟教程'
小于 {:{$lt:}} db.col.find({"likes":{$lt:50}}).pretty() where likes < 50
小于或等于 {:{$lte:}} db.col.find({"likes":{$lte:50}}).pretty() where likes <= 50
大于 {:{$gt:}} db.col.find({"likes":{$gt:50}}).pretty() where likes > 50
大于或等于 {:{$gte:}} db.col.find({"likes":{$gte:50}}).pretty() where likes >= 50
不等于 {:{$ne:}} db.col.find({"likes":{$ne:50}}).pretty() where likes != 50
  • query :可选,使用查询操作符指定查询条件

  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

格式

db.collection.find(query, projection)
> db.collection.find({},{_id:true})
{ "_id" : ObjectId("621746c633498943fd27da03") }
{ "_id" : ObjectId("621746ea33498943fd27da04") }
db.collection.find({},{_id:false}).pretty()
{ "name" : "wxh" }
{ "name" : "wxh", "AGE" : 34 }

AND 条件

> db.col.find({key1:value1, key2:value2}).pretty()
> db.col.find({"by":"菜鸟教程", "title":"MongoDB 教程"}).pretty()

OR 条件

> db.col.find(
   {
      $or: [
         {key1: value1}, {key2:value2}
      ]
   }
).pretty()
> db.col.find({$or:[{"by":"菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()

AND 和 OR 联合使用

>db.col.find({"likes": {$gt:50}, $or: [{"by": "菜鸟教程"},{"title": "MongoDB 教程"}]}).pretty()

$type操作符

MongoDB 中可以使用的类型如下表所示

类型数字备注
Double 1  
String 2  
Object 3  
Array 4  
Binary data 5  
Undefined 6 已废弃。
Object id 7  
Boolean 8  
Date 9  
Null 10  
Regular Expression 11  
JavaScript 13  
Symbol 14  
JavaScript (with scope) 15  
32-bit integer 16  
Timestamp 17  
64-bit integer 18  
Min key 255 Query with -1.
Max key 127  

获取集合field为String的数据

db.col.find({"title" : {$type : 2}})
或
db.col.find({"title" : {$type : 'string'}})

 

Limit()与Skip()与sort()

skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit()

{ "_id" : ObjectId("56066542ade2f21f36b0313a"), "title" : "PHP 教程", "description" : "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "php" ], "likes" : 200 }
{ "_id" : ObjectId("56066549ade2f21f36b0313b"), "title" : "Java 教程", "description" : "Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "java" ], "likes" : 150 }
{ "_id" : ObjectId("5606654fade2f21f36b0313c"), "title" : "MongoDB 教程", "description" : "MongoDB 是一个 Nosql 数据库", "by" : "菜鸟教程", "url" : "http://www.runoob.com", "tags" : [ "mongodb" ], "likes" : 100 }

limit()

db.COLLECTION_NAME.find().limit(NUMBER)

NUMBER: 从MongoDB中读取的记录条数

> db.col.find({},{"title":1,_id:0}).limit(2)
{ "title" : "PHP 教程" }
{ "title" : "Java 教程" }

Skip()

还可以使用skip()方法来跳过指定数量的数据

> db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
> db.col.find({},{"title":1,_id:0}).limit(1).skip(1)
{ "title" : "Java 教程" }

sort()

其中 1 为升序排列

而 -1 是用于降序排列

db.COLLECTION_NAME.find().sort({KEY:1})
> db.col.find({},{"title":1,_id:0}).sort({"likes":-1})

 

聚合

> db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
表达式描述实例
$sum 计算总和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 计算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 获取集合中所有文档对应值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 获取集合中所有文档对应值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 将值加入一个数组中,不会判断是否有重复的值。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 将值加入一个数组中,会判断是否有重复的值,若相同的值在数组中已经存在了,则不加入。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根据资源文档的排序获取第一个文档数据。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根据资源文档的排序获取最后一个文档数据 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])

类似

select by_user, count(*) from mycol group by by_user

管道

$project:返回文档结构

$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档

主要用于重命名、增加和删除字段

#结果中就只还有tilte和author
> db.article.aggregate(
    { $project : {
    _id : 0 ,
    title : 1 ,
    author : 1 ,
    }}
);
​
#重命名字段名和子文档的字段名
db.article.aggregate({ 
    $project : {
        title : 1 ,
        page_views : "$pageViews" ,
        bar : "$other.foo"
}});
$match:过滤数据

$match: 筛选符合条件文档,作为下一阶段的输入

1.不能在$match操作符中使用$where表达式操作符。

2.$match尽量出现在管道的前面,这样可以提早过滤文档,加快聚合速度。

3.如果$match出现在最前面的话,可以使用索引来加快查询。

db.articles.aggregate( [
{ 
    $match : { score : { $gt : 70, $lte : 90 } } 
},
{ 
    $group: { _id: null, count: { $sum: 1 } } 
}
] );
$limit:限制返回文档数

$limit: 限制经过管道的文档数量

db.article.aggregate({ $limit : 5 });
$skip:跳过指定数量的文档

$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档

db.article.aggregate({ $skip : 5 });
$unwind:拆分数组字段

$unwind: 将数组元素拆分为独立字段

> db.article.find()
​
{
  "_id" : ObjectId("528751b0e7f3eea3d1412ce2"),
  "author" : "Jone", "title" : "Abook",
  "tags" : [  "good",  "fun",  "good" ] 
 }
 
> db.article.aggregate({$project:{author:1,title:1,tags:1}},{$unwind:"$tags"})
​
{
    "result" : [{
        "_id" : bjectId("528751b0e7f3eea3d1412ce2"),
        "author" : "Jone",
        "title" : "A book",
        "tags" : "good"
    },
    {
        "_id" : ObjectId("528751b0e7f3eea3d1412ce2"),
        "author" : "Jone",
        "title" : "A book",
        "tags" : "fun"
    },
    {
        "_id" : ObjectId("528751b0e7f3eea3d1412ce2"),
        "author" : "Jone",
        "title" : "A book",
        "tags" : "good"
    }],
    "ok" : 1
}
$group:文档分组

$group:将集合中的文档分组,可用于统计结果

db.article.aggregate({ 
    $group : {
        _id : "$author",
        docsPerAuthor : { $sum : 1 },
        viewsPerAuthor : { $sum : "$pageViews" }
    }
});
$sort:文档排序

$sort:将输入文档排序后输出

$sort出现在$limit之前的话,$sort只会对前$limit个文档进行操作

db.users.aggregate( { 
    $sort : { age : -1, posts: 1 } 
});

 

关联关系

MongoDB 中的关系可以是:

  • 1:1 (1对1)

  • 1: N (1对多)

  • N: 1 (多对1)

  • N: N (多对多)

嵌入式关系

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address": [
      {
         "building": "22 A, Indiana Apt",
         "pincode": 123456,
         "city": "Los Angeles",
         "state": "California"
      },
      {
         "building": "170 A, Acropolis Apt",
         "pincode": 456789,
         "city": "Chicago",
         "state": "Illinois"
      }]
} 

查询地址

> db.collection.findOne({"name":"Tom Benzamin"},{"address":1})
{
    "_id" : ObjectId("621c3e91d7dbca87f3020a34"),
    "address" : [
        {
            "building" : "22 A, Indiana Apt",
            "pincode" : 123456,
            "city" : "Los Angeles",
            "state" : "California"
        },
        {
            "building" : "170 A, Acropolis Apt",
            "pincode" : 456789,
            "city" : "Chicago",
            "state" : "Illinois"
        }
    ]
}

引用式关系

{
   "_id":ObjectId("52ffc33cd85242f436000001"),
   "contact": "987654321",
   "dob": "01-01-1991",
   "name": "Tom Benzamin",
   "address_ids": [
      ObjectId("52ffc4a5d85242602e000000"),
      ObjectId("52ffc4a5d85242602e000001")
   ]
}
> var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
> var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})
 

 

 

posted @ 2022-03-04 09:38  minnersun  阅读(39)  评论(0编辑  收藏  举报