锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. MongoDB基本CURD命令

MongoDB基本CURD命令

0
  • 软件开发
  • 发布于 2024-08-19
  • 10 次阅读
黄健
黄健

MongoDB的基本操作

选择和创建数据库

  • 选择和创建数据库的语法格式:
use 数据库名称
  • 如果数据库不存在则自动创建,例如,以下语句创建spitdb 数据库:
use articledb
  • 查看有权限查看的所有的数据库命令
show dbs
或
show databases

注意: 在 MongoDB 中,集合只有在内容插入后才会创建! 就是说,创建集合(数据表)后要再插入一个文档(记录),集合才会真正创建。

  • 查看当前正在使用的数据库命令
db

MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中。

另外:
数据库名可以是满足以下条件的任意UTF-8字符串。

  • 不能是空字符串("")。

  • 不得含有' '(空格)、.、$、/、\和\0 (空字符)。

  • 应全部小写。

  • 最多64字节。

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

  • admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特

  • 定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。

  • local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合

  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

数据库的删除

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

db.dropDatabase() #删除当前数据库

提示:主要用来删除已经持久化的数据库

集合操作

集合,类似关系型数据库中的表。
可以显示的创建,也可以隐式的创建。

集合的显式创建

  • 基本语法格式:

    db.createCollection(name)
    
  • 参数说明:
    name: 要创建的集合名称
    例如:创建一个名为mycollection 的普通集合。

    db.createCollection("mycollection")
    
  • 查看当前库中的表:show tables命令

    show collections
    或
    show tables
    

集合的命名规范:

  • 集合名不能是空字符串""。

  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。

  • 集合名不能以"system."开头,这是为系统集合保留的前缀。

  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。

集合的隐式创建

当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合。
通常我们使用隐式创建文档即可,后面CURD操作的部分会有详细说明。

db.collection.insert(
  <document or array of documents>,
  {
   
	writeConcern: <document>,
	ordered: <boolean>
  }
)

集合的删除

集合删除语法格式如下:

db.collection.drop()
或
db.集合名.drop()

返回值
如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
例如:要删除mycollection集合

db.mycollection.drop()

MongoDB集合数据操作(CURD)

数据添加

  1. 插入单条数据 db.集合名.insert(文档)
    文档的数据结构和JSON基本一样。
    所有存储在集合中的数据都是BSON格式。
    BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。
  2. 例如:
    db.comment.insert({"articleid":"100000","content":"今天天气真好,阳光明媚","userid":"1001","nickname":"Rose","createdatetime":new Date(),"likenum":NumberInt(10),"state":null})
    没有指定 _id 这个字段 系统会自动生成 当然我们也可以指定 _id( _id 类型是ObjectId 类型是一个12字节 BSON 类型数据,有以下格式:
    前4个字节表示时间戳 ObjectId("对象Id字符串").getTimestamp() 来获取接下来的3个字节是机器标识码紧接的两个字节由进程id组成(PID)最后三个字节是随机数。)
  3. 插入多条数据
    db.集合名.insert([文档,文档])
单个文档插入

使用insert() 或 save() 方法向集合中插入文档,语法如下:

db.collection.insert(
  <document or array of documents>,
  {
   
    writeConcern: <document>,
    ordered: <boolean>
  }
)

参数:

ParameterTypeDescription
documentdocument or array要插入到集合中的文档或文档数组。((json格式)
writeConcerndocumentOptional. A document expressing the write concern. Omit to use the default write concern. See Write Concern.Do not explicitly set the write concern for the operation if run in a transaction. To use write concern with transactions, see Transactions and Write Concern.
orderedboolean可选。如果为真,则按顺序插入数组中的文档,如果其中一个文档出现错误,MongoDB将返回而不处理数组中的其余文档。如果为假,则执行无序插入,如果其中一个文档出现错误,则继续处理数组中的主文档。在版本2.6+中默认为true

【示例】
要向comment的集合(表)中插入一条测试数据:

db.comment.insert({
   "articleid":"100000","content":"今天天气真好,阳光明媚","userid":"1001","nickname":"Rose","createdatetime":new Date(),"likenum":NumberInt(10),"state":null})

提示:
1)comment集合如果不存在,则会隐式创建
2)mongo中的数字,默认情况下是double类型,如果要存整型,必须使用函数NumberInt(整型数字),否则取出来就有问题了。
3)插入当前日期使用new Date()
4)插入的数据没有指定_id ,会自动生成主键值
5)如果某字段没值,可以赋值为null,或不写该字段。

执行后,如下,说明插入一个数据成功了。

WriteResult({
    "nInserted" : 1 })

注意:

  1. 文档中的键/值对是有序的。
  2. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
  3. MongoDB区分类型和大小写。
  4. MongoDB的文档不能有重复的键。
  5. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。

文档键命名规范:

  • 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
  • . 和$有特别的意义,只有在特定环境下才能使用。
  • 以下划线"_"开头的键是保留的(不是严格要求的)。
批量插入

语法:

db.collection.insertMany(
  [ <document 1> , <document 2>, ... ],
  {
   
	writeConcern: <document>,
	ordered: <boolean>
  }
)

【示例】
批量插入多条文章评论:

db.comment.insertMany([{
   "_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。","userid":"1002","nickname":"相忘于江湖","createdatetime":new Date("2019-08-05T22:08:15.522Z"),"likenum":NumberInt(1000),"state":"1"},
{
   "_id":"2","articleid":"100001","content":"我夏天空腹喝凉开水,冬天喝温开水","userid":"1005","nickname":"伊人憔悴","createdatetime":new Date("2019-08-05T23:58:51.485Z"),"likenum":NumberInt(888),"state":"1"},
{
   "_id":"3","articleid":"100001","content":"我一直喝凉开水,冬天夏天都喝。","userid":"1004","nickname":"杰克船长","createdatetime":new Date("2019-08-06T01:05:06.321Z"),"likenum":NumberInt(666),"state":"1"},
{
   "_id":"4","articleid":"100001","content":"专家说不能空腹吃饭,影响健康。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-06T08:18:35.288Z"),"likenum":NumberInt(2000),"state":"1"},
{
   "_id":"5","articleid":"100001","content":"研究表明,刚烧开的水千万不能喝,因为烫嘴。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-06T11:01:02.521Z"),"likenum":NumberInt(3000),"state":"1"}
]);

提示:
插入时指定了_id ,则主键就是该值。
如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。
因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理。如(了解):

try {
   
	db.comment.insertMany([{
   "_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。","userid":"1002","nickname":"相忘于江湖","createdatetime":new Date("2019-08-05T22:08:15.522Z"),"likenum":NumberInt(1000),"state":"1"},
	{
   "_id":"2","articleid":"100001","content":"我夏天空腹喝凉开水,冬天喝温开水","userid":"1005","nickname":"伊人憔悴","createdatetime":new Date("2019-08-05T23:58:51.485Z"),"likenum":NumberInt(888),"state":"1"},
	{
   "_id":"3","articleid":"100001","content":"我一直喝凉开水,冬天夏天都喝。","userid":"1004","nickname":"杰克船长","createdatetime":new Date("2019-08-06T01:05:06.321Z"),"likenum":NumberInt(666),"state":"1"},
	{
   "_id":"4","articleid":"100001","content":"专家说不能空腹吃饭,影响健康。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-06T08:18:35.288Z"),"likenum":NumberInt(2000),"state":"1"},
	{
   "_id":"5","articleid":"100001","content":"研究表明,刚烧开的水千万不能喝,因为烫嘴。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-06T11:01:02.521Z"),"likenum":NumberInt(3000),"state":"1"}
	]);
} catch (e) {
   
	print (e);
}

数据查询

查询数据的语法格式如下:

db.collection.find(<query>, [projection])

参数:

ParameterTypeDescription
querydocument可选。使用查询运算符指定选择筛选器。若要返回集合中的所有文档,请省略此参数或传递空文档( {} )。
projectiondocument可选。指定要在与查询筛选器匹配的文档中返回的字段(投影)。若要返回匹配文档中的所有字段,请省略此参数。
查询所有

如果我们要查询spit集合的所有文档,我们输入以下命令

db.comment.find()
或
db.comment.find({
   })

  这里你会发现每条文档会有一个叫_id的字段,这个相当于我们原来关系数据库中表的主键,当你在插入文档记录时没有指定该字段,MongoDB会自动创建,其类型是ObjectID类型。

  如果我们在插入文档记录时指定该字段也可以,其类型可以是ObjectID类型,也可以是MongoDB支持的任意类型。如果我想按一定条件来查询,比如我想查询userid为1003的记录,怎么办?很简单!只 要在find()中添加参数即可,参数也是json格式,如下:

db.comment.find({
   userid:'1003'})
投影查询(Projection Query):

如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。如:查询结果只显示_id、userid、nickname:

db.comment.find({
   userid:"1003"},{
   userid:1,nickname:1})

默认_id 会显示。
如:查询结果只显示、userid、nickname ,不显示_id :

db.comment.find({
   userid:"1003"},{
   userid:1,nickname:1,_id:0})


再例如:查询所有数据,但只显示_id、userid、nickname :

db.comment.find({
   },{
   userid:1,nickname:1})

统计查询

统计查询使用count()方法,语法如下:

db.collection.count(query, options)

参数:

ParameterTypeDescription
querydocument查询选择条件。
optionsdocument可选。

【示例】
(1)统计所有记录数:
统计comment集合的所有的记录数:

db.comment.count()

(2)按条件统计记录数:
例如:统计userid为1003的记录条数

db.comment.count({
   userid:"1003"})

提示:
默认情况下count() 方法返回符合条件的全部记录条数。

分页列表查询

可以使用limit()方法来读取指定数量的数据,使用skip()方法来跳过指定数量的数据。
基本语法如下所示:

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

如果你想返回指定条数的记录,可以在find方法后调用limit来返回结果(TopN),默认值20,例如:

db.comment.find().limit(3)

skip方法同样接受一个数字参数作为跳过的记录条数。(前N个不要),默认值是0

db.comment.find().skip(3)

分页查询:需求:每页2个,第二页开始:跳过前两条数据,接着值显示3和4条数据

//第一页
db.comment.find().skip(0).limit(2)
//第二页
db.comment.find().skip(2).limit(2)
//第三页
db.comment.find().skip(4).limit(2)
排序查询

sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。
语法如下所示:

db.COLLECTION_NAME.find().sort({
   KEY:1})
或
db.集合名称.find().sort(排序方式)

例如:
对userid降序排列,并对访问量进行升序排列

db.comment.find().sort({
   userid:-1,likenum:1})

提示:
skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit(),和命令编写顺序无关。

比较条件查询

db.集合名.find(条件)

操作条件格式例子RDBMS中的条件
等于{key:value}db.col.find({字段名:值}).pretty()where 字段名=值
大于{key:{$gt:value}}db.col.find({字段名:{$gt:值}}).pretty()where 字段名>值
小于{key:{$lt:value}}db.col.find({字段名:{$lt:值}}).pretty()where 字段名<值
大于等于{key:{$gte:value}}db.col.find({字段名:{$gte:值}}).pretty()where 字段名>=值
小于等于{key:{$lte:value}}db.col.find({字段名:{$lte:值}}).pretty()where 字段名<=值
不等于{key:{$ne:value}}db.col.find({字段名:{$ne:值}}).pretty()where 字段名!=值
db.集合名称.find({
    "field" : {
    $gt: value }}) // 大于: field > value
db.集合名称.find({
    "field" : {
    $lt: value }}) // 小于: field < value
db.集合名称.find({
    "field" : {
    $gte: value }}) // 大于等于: field >= value
db.集合名称.find({
    "field" : {
    $lte: value }}) // 小于等于: field <= value
db.集合名称.find({
    "field" : {
    $ne: value }}) // 不等于: field != value

示例:查询评论点赞数量大于700的记录

db.comment.find({
   likenum:{
   $gt:NumberInt(700)}})
包含查询

包含使用$in操作符。 示例:查询评论的集合中userid字段包含1003或1004的文档

db.comment.find({
   userid:{
   $in:["1003","1004"]}})

不包含使用$nin操作符。 示例:查询评论集合中userid字段不包含1003和1004的文档

db.comment.find({
   userid:{
   $nin:["1003","1004"]}})
正则的复杂条件查询

MongoDB的模糊查询是通过正则表达式的方式实现的。格式为:

db.collection.find({
   field:/正则表达式/})
或
db.集合.find({
   字段:/正则表达式/})

提示:正则表达式是js的语法,直接量的写法。
例如,我要查询评论内容包含"开水"的所有文档,代码如下:

db.comment.find({
   content:/开水/})

如果要查询评论的内容中以"专家"开头的,代码如下:

db.comment.find({
   content:/^专家/})
逻辑条件查询

我们如果需要查询同时满足两个以上条件,需要使用$and操作符将条件进行关联。(相 当于SQL的and) 格式为:

$and:[ {
    },{
    },{
    } ]

示例:查询评论集合中likenum大于等于700 并且小于2000的文档:

db.comment.find({
   $and:[{
   likenum:{
   $gte:NumberInt(700)}},{
   likenum:{
   $lt:NumberInt(2000)}}]})

如果两个以上条件之间是或者的关系,我们使用 操作符进行关联,与前面 and的使用方式相同 格式为:

$or:[ {
    },{
    },{
    } ]

示例:查询评论集合中userid为1003,或者点赞数小于1000的文档记录

db.comment.find({
   $or:[ {
   userid:"1003"} ,{
   likenum:{
   $lt:1000} }]})

如果要使用取反条件,则使用not,语法如下

db.集合名.find({
   key:{
   $not:{
   $操作符:value}})

示例:找到用户id不是1003的所有文章

db.comment.find({
   userid:{
   $not:{
   $eq: "1003"}}})

数据更新

更新文档的语法:

$set :设置字段值
$unset :删除指定字段
$inc:对修改的值进行自增

db.collection.update(query, update, options)
//或
db.collection.update(
	<query>,
	<update>,
	{
   
		upsert: <boolean>,
		multi: <boolean>,
		writeConcern: <document>,
		collation: <document>,
		arrayFilters: [ <filterdocument1>, ... ],
		hint: <document|string> // Available starting in MongoDB 4.2
	}
)

参数说明:
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如$set,$inc...)等,也可以理解为sql update中set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,MongoDB 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,用来指定mongod对写操作的回执行为比如写的行为是否需要确认。

举例:
db.集合名.update({
   条件},{
   $set:{
   字段名:值}},{
   multi:true})
writeConcern 包括以下字段:
{ w: <value>, j: <boolean>, wtimeout: <number> }
w:指定写操作传播到的成员数量
比如:
w=1(默认):则要求得到写操作已经传播到独立的Mongod实例或副本集的primary成员的确认
w=0:则不要求确认写操作,可能会返回socket exceptions和 networking errors
w="majority":要求得到写操作已经传播到大多数具有存储数据具有投票的(data-bearing voting)成员(也就是 members[n].votes 值大于0的成员)的确认
j:要求得到Mongodb的写操作已经写到硬盘日志的确认
比如:
j=true:要求得到Mongodb(w指定的实例个数)的写操作已经写到硬盘日志的确认。j=true本身并不保证
因为副本集故障而不会回滚。
wtimeout:指定write concern的时间限制,只适用于w>1的情况wtimeout在超过指定时间后写操作会返回error,即使写操作最后执行成功,当这些写操作返回时,MongoDB不会撤消在wtimeout时间限制之前执行成功的数据修改。

如果未指定wtimeout选项且未指定write concern级别,则写入操作将无限期阻止。 指定wtimeout值为0等同于没有wtimeout选项。
覆盖的修改

如果我们想修改_id为1的记录,点赞量为1001,输入以下语句:

db.comment.update({
   _id:"1"},{
   likenum:NumberInt(1001)})

执行后,我们会发现,这条文档除了likenum字段其它字段都不见了,

局部修改

为了解决上面其他字段消失的问题,我们需要使用修改器$set来实现,命令如下:
我们想修改_id为2的记录,浏览量为889,输入以下语句:

db.comment.update({
   _id:"2"},{
   $set:{
   likenum:NumberInt(889)}})
批量的修改

更新所有用户为1003 的用户的昵称为凯撒大帝。

//默认只修改第一条数据
db.comment.update({
   userid:"1003"},{
   $set:{
   nickname:"凯撒2"}})
//修改所有符合条件的数据
db.comment.update({
   userid:"1003"},{
   $set:{
   nickname:"凯撒大帝"}},{
   multi:true})

提示:如果不加后面的参数,则只更新符合条件的第一条记录

列值增长的修改

如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用$inc 运算符来实现。
需求:对3号数据的点赞数,每次递增1

db.comment.update({
   _id:"3"},{
   $inc:{
   likenum:NumberInt(1)}})

数据删除

db.collection.remove(
	<query>,
	{
   
		justOne: <boolean>,
		writeConcern: <document>
	}
)
参数说明:
query :(可选)删除的文档的条件。
justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值
false,则删除所有匹配条件的文档。
writeConcern :(可选)用来指定mongod对写操作的回执行为。

以下语句可以将数据全部删除,请慎用

db.comment.remove({
   })

如果删除_id=1的记录,输入以下语句

db.comment.remove({
   _id:"1"})

如果要删除自动生成的主键 _id,需要使用下面的语句

db.company.remove({
   _id:ObjectID("6109da13daee897330578f78")})

常用命令小结

选择切换数据库:use articledb
插入数据:db.comment.insert({
   bson数据})
查询所有数据:db.comment.find();
条件查询数据:db.comment.find({
   条件})
查询符合条件的第一条记录:db.comment.findOne({
   条件})
查询符合条件的前几条记录:db.comment.find({
   条件}).limit(条数)
查询符合条件的跳过的记录:db.comment.find({
   条件}).skip(条数)
修改数据:db.comment.update({
   条件},{
   修改后的数据}) 或db.comment.update({
   条件},{
   $set:{
   要修改部分的字段:数据})
修改数据并自增某字段值:db.comment.update({
   条件},{
   $inc:{
   自增的字段:步进值}})
删除数据:db.comment.remove({
   条件})
统计查询:db.comment.count({
   条件})
模糊查询:db.comment.find({
   字段名:/正则表达式/})
条件比较运算:db.comment.find({
   字段名:{
   $gt:值}})
包含查询:db.comment.find({
   字段名:{
   $in:[值1,值2]}})或db.comment.find({
   字段名:{
   $nin:[值1,值2]}})
条件连接查询:db.comment.find({
   $and:[{
   条件1},{
   条件2}]})或db.comment.find({
   $or:[{
   条件1},{
   条件2}]})

MongoDB 聚合操作

聚合操作简介

  聚合是MongoDB的高级查询语言,它允许我们通过转化合并由多个文档的数据来生成新的在单个文档里不存在的文档信息。一般都是将记录按条件分组之后进行一系列求最大值,最小值,平均值的简单操作,也可以对记录进行复杂数据统计,数据挖掘的操作。聚合操作的输入是集中的文档,输出可以是一个文档也可以是多个文档。

MongoDB 聚合操作分类

  • 单目的聚合操作(Single Purpose Aggregation Operation)
  • 聚合管道(Aggregation Pipeline)
  • MapReduce 编程模型

单目的聚合操作

单目的聚合命令常用的有:count() 和 distinct()

db.lg_resume_preview.find({
   }).count()

聚合管道(Aggregation Pipeline)

db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
如:
db.lg_resume_preview.aggregate([{
   $group:{
   _id:"$city",city_count:{
   $sum:1}}}])

MongoDB中聚合(aggregate)主要用于统计数据(诸如统计平均值,求和等),并返回计算后的数据结果。
表达式:处理输入文档并输出。表达式只能用于计算当前聚合管道的文档,不能处理其它的文档。

表达式描述
$sum计算总和
$avg计算平均值
$min获取集合中所有文档对应值得最小值
$max获取集合中所有文档对应值得最大值
$push在结果文档中插入值到一个数组中
$addToSet在结果文档中插入值到一个数组中,但数据不重复
$first根据资源文档的排序获取第一个文档数据
$last根据资源文档的排序获取最后一个文档数据

MongoDB 中使用 db.COLLECTION_NAME.aggregate([{},...]) 方法来构建和使用聚合管道,每个文档通过一个由一个或者多个阶段(stage)组成的管道,经过一系列的处理,输出相应的结果。

MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

这里我们介绍一下聚合框架中常用的几个操作:

  • $group:将集合中的文档分组,可用于统计结果。
  • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
  • match:用于过滤数据,只输出符合条件的文档。match使用MongoDB的标准查询操作。
  • $limit:用来限制MongoDB聚合管道返回的文档数。
  • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
  • $sort:将输入文档排序后输出。
  • $geoNear:输出接近某一地理位置的有序文档。

查询用户的平均点赞数

db.comment.aggregate([{
   $group: {
    _id: "$userid", likenum_count:{
   $avg: "$likenum"}}},
                    {
   $project: {
   user:"$userid", avg_like:"$likenum_count"}}])


查询平均点赞数在1000以上的用户

db.comment.aggregate([{
   $group: {
    _id: "$userid", likenum_count:{
   $sum: "$likenum"}}},
                    {
   $match: {
   likenum_count:{
   $gt:1000}}}])

MapReduce 编程模型

  Pipeline查询速度快于MapReduce,但是MapReduce的强大之处在于能够在多台Server上并行执行复杂的聚合逻辑。MongoDB不允许Pipeline的单个聚合操作占用过多的系统内存,如果一个聚合操作消耗20%以上的内存,那么MongoDB直接停止操作,并向客户端输出错误消息。

  MapReduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE)。

db.collection.mapReduce(
	function() {
   emit(key,value);}, //map 函数
	function(key,values) {
   return reduceFunction}, //reduce 函数
	{
   
		out: collection,
		query: document,
		sort: document,
		limit: number,
		finalize: <function>,
		verbose: <boolean>
	}
)

使用 MapReduce 要实现两个函数 Map 函数和 Reduce 函数,Map 函数调用 emit(key, value), 遍历collection 中所有的记录, 将 key 与 value 传递给 Reduce 函数进行处理。

参数说明:

  • map:是JavaScript 函数,负责将每一个输入文档转换为零或多个文档,生成键值对序列,作为reduce 函数参数

  • reduce:是JavaScript 函数,对map操作的输出做合并的化简的操作(将key-value变成keyvalues,也就是把values数组变成一个单一的值value)

  • out:统计结果存放集合

  • query: 一个筛选条件,只有满足条件的文档才会调用map函数。

  • sort: 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制

  • limit: 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)

  • finalize:可以对reduce输出结果再一次修改

  • verbose:是否包括结果信息中的时间信息,默认为fasle

统计点赞数大于800的文章,计算这些文章的作者的在上述条件筛选后的文章的平均点赞数

db.comment.mapReduce(function() {
   emit(this.userid, this.likenum)}, 
                        function(key, value) {
   return Array.avg(value)},
                        {
   
                            query:{
   likenum:{
   $gt:800}},
                            out:"likenum_avg"    
                        }
                    )

原文链接: https://blog.csdn.net/Kiven_ch/article/details/119299226

标签: #MongoDB 13 #软件开发 1171
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.