Mongodb 多文档聚合操作处理方法(单一聚合)

这篇具有很好参考价值的文章主要介绍了Mongodb 多文档聚合操作处理方法(单一聚合)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

聚合

聚合操作处理多个文档并返回计算结果。您可以使用聚合操作来:

  • 将多个文档中的值分组在一起。

  • 对分组数据执行操作以返回单个结果。

  • 分析数据随时间的变化。

要执行聚合操作,您可以使用:

  • 聚合管道

  • 单一目的聚合方法

  • Map-reduce 函数

单一目的聚合方法

所有这些操作都会聚合来自单个集合的文档。虽然这些操作提供了对常见聚合过程的简单访问,但它们缺乏聚合管道的灵活性和功能。

常用的单一聚合操作,包括 count() 获取文档的总数量 、 distinct() 获取字段不重复的值、estimatedDocumentCount()

count

定义: db.collection.count(query, options), find()返回与集合或视图的查询匹配的文档计数 。 db.collection.count()方法不执行 find()操作,而是计算并返回与查询匹配的结果数。

  • count() 相当于构造 db.collection.find(query).count()。
  • 在分片集群上,db.collection.count() 如果 存在孤立文档或正在进行块迁移,则不使用查询谓词可能会导致计数不准确。为了避免这些情况,在分片集群上,使用以下 db.collection.aggregate()方法
  • 孤立文档: 在分片集群中,孤立文档是指某个分片上的那些文档,由于迁移失败或由于异常关闭而导致迁移清理不完整,因此也存在于其他分片上的块中。
  • 从 MongoDB 4.4 开始,孤立文档会在块迁移完成后自动清理。您不再需要运行cleanupOrphaned来删除孤立文档。
# 查询总数量 
sit_rs1:PRIMARY> db.user.count() 
6

# 此操作等效于以下操作:
sit_rs1:PRIMARY> db.user.find().count() 
6

# 分片集群,使用 aggregate 
sit_rs1:PRIMARY> db.user.aggregate( [{ $count: "myCount" }])
{ "myCount" : 6 }


# 该$count阶段相当于以下 $group+$project序列:
sit_rs1:PRIMARY> db.user.aggregate( [{ $group: { _id: null, count: { $sum: 1 } } },  { $project: { _id: 0 } }] )
{ "count" : 6 }

查询匹配的文档操作,使用 带 Query 的 Count , 计算与查询匹配的所有文档的数量, 如下

# 查询 name 为 user1 的文档数量 
sit_rs1:PRIMARY> db.user.count({"name" : "user1"})
1

# 该查询等效于以下内容:
sit_rs1:PRIMARY> db.user.find({"name" : "user1"}).count()
1

distinct

定义: db.collection.distinct(field, query, options)。 在单个集合或视图中查找指定字段的不同值,并以数组形式返回结果。

  • 在分片集群中,该distinct命令可能会返回 孤立的文档
  • 如果指定的值field是一个数组, db.collection.distinct() 将数组的每个元素视为单独的值。

插入测试数据 : item 字段为嵌入文档、number字段为数组, 如下:

sit_rs1:PRIMARY> db.user.drop()
sit_rs1:PRIMARY> db.user.insertMany([
...  { name: "user1", age: 10, item: {"A": 111, "B": 211}, number: [ { "n1":2, "n2":6 }, { "n1":3, "n2":3 }, { "n1":5, "n2":6 } ] },
...  { name: "user2", age: 20, item: {"A": 112, "B": 212}, number: [ { "n1":1, "n2":3 }, { "n1":4, "n2":5 }, { "n1":7, "n2":6 } ] },
...  { name: "user3", age: 30, item: {"A": 113, "B": 213}, number: [ { "n1":1, "n2":8 }, { "n1":2, "n2":6 }, { "n1":2, "n2":6 } ] },
...  { name: "user4", age: 45, item: {"A": 111, "B": 211}, number: [ { "n1":9, "n2":6 }, { "n1":2, "n2":4 }, { "n1":3, "n2":6 } ] },
...  { name: "user5", age: 55, item: {"A": 112, "B": 215}, number: [ { "n1":7, "n2":8 }, { "n1":8, "n2":4 }, { "n1":4, "n2":6 } ] },
...  { name: "user6", age: 55, item: {"A": 115, "B": 212}, number: [ { "n1":5, "n2":5 }, { "n1":8, "n2":5 }, { "n1":7, "n2":6 } ] },
...  { name: "user7", age: 45, item: {"A": 116, "B": 216}, number: [ { "n1":6, "n2":6 }, { "n1":8, "n2":5 }, { "n1":7, "n2":6 } ] },
...  { name: "user8", age: 60, item: {"A": 113, "B": 211}, number: [ { "n1":5, "n2":4 }, { "n1":8, "n2":5 }, { "n1":7, "n2":6 } ] },
...  { name: "user9", age: 75, item: {"A": 118, "B": 218}, number: [ { "n1":1, "n2":3 }, { "n1":8, "n2":5 }, { "n1":7, "n2":6 } ] }
... ])
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("64b8d2404b442dde59447cf0"),
                ObjectId("64b8d2404b442dde59447cf1"),
                ObjectId("64b8d2404b442dde59447cf2"),
                ObjectId("64b8d2404b442dde59447cf3"),
                ObjectId("64b8d2404b442dde59447cf4"),
                ObjectId("64b8d2404b442dde59447cf5"),
                ObjectId("64b8d2404b442dde59447cf6"),
                ObjectId("64b8d2404b442dde59447cf7"),
                ObjectId("64b8d2404b442dde59447cf8")
        ]
}

sit_rs1:PRIMARY> db.user.find()
{ "_id" : ObjectId("64b8d2404b442dde59447cf1"), "name" : "user2", "age" : 20, "item" : { "A" : 112, "B" : 212 }, "number" : [ { "n1" : 1, "n2" : 3 }, { "n1" : 4, "n2" : 5 }, { "n1" : 7, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf4"), "name" : "user5", "age" : 55, "item" : { "A" : 112, "B" : 215 }, "number" : [ { "n1" : 7, "n2" : 8 }, { "n1" : 8, "n2" : 4 }, { "n1" : 4, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf2"), "name" : "user3", "age" : 30, "item" : { "A" : 113, "B" : 213 }, "number" : [ { "n1" : 1, "n2" : 8 }, { "n1" : 2, "n2" : 6 }, { "n1" : 2, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf6"), "name" : "user7", "age" : 45, "item" : { "A" : 116, "B" : 216 }, "number" : [ { "n1" : 6, "n2" : 6 }, { "n1" : 8, "n2" : 5 }, { "n1" : 7, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf0"), "name" : "user1", "age" : 10, "item" : { "A" : 111, "B" : 211 }, "number" : [ { "n1" : 2, "n2" : 6 }, { "n1" : 3, "n2" : 3 }, { "n1" : 5, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf3"), "name" : "user4", "age" : 45, "item" : { "A" : 111, "B" : 211 }, "number" : [ { "n1" : 9, "n2" : 6 }, { "n1" : 2, "n2" : 4 }, { "n1" : 3, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf8"), "name" : "user9", "age" : 75, "item" : { "A" : 118, "B" : 218 }, "number" : [ { "n1" : 1, "n2" : 3 }, { "n1" : 8, "n2" : 5 }, { "n1" : 7, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf5"), "name" : "user6", "age" : 55, "item" : { "A" : 115, "B" : 212 }, "number" : [ { "n1" : 5, "n2" : 5 }, { "n1" : 8, "n2" : 5 }, { "n1" : 7, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf7"), "name" : "user8", "age" : 60, "item" : { "A" : 113, "B" : 211 }, "number" : [ { "n1" : 5, "n2" : 4 }, { "n1" : 8, "n2" : 5 }, { "n1" : 7, "n2" : 6 } ] }

查询 user 表中 age 字段的不同值, distinct 返回数组元素,如果需要统计其字段,请使用 length , 如下

# 查询全表,返回9行数据 
sit_rs1:PRIMARY> db.user.find({}, {age:1})
{ "_id" : ObjectId("64b8d2404b442dde59447cf1"), "age" : 20 }
{ "_id" : ObjectId("64b8d2404b442dde59447cf4"), "age" : 55 }
{ "_id" : ObjectId("64b8d2404b442dde59447cf2"), "age" : 30 }
{ "_id" : ObjectId("64b8d2404b442dde59447cf6"), "age" : 45 }
{ "_id" : ObjectId("64b8d2404b442dde59447cf0"), "age" : 10 }
{ "_id" : ObjectId("64b8d2404b442dde59447cf3"), "age" : 45 }
{ "_id" : ObjectId("64b8d2404b442dde59447cf8"), "age" : 75 }
{ "_id" : ObjectId("64b8d2404b442dde59447cf5"), "age" : 55 }
{ "_id" : ObjectId("64b8d2404b442dde59447cf7"), "age" : 60 }

# 查询 user 表中 age 字段的不同值,其中重复的45、55只出现一次
sit_rs1:PRIMARY> db.user.distinct("age")
[ 10, 20, 30, 45, 55, 60, 75 ]

# 统计distinct返回的元素个数
sit_rs1:PRIMARY> db.user.distinct("age").length
7

返回数组字段的不同值, 以下示例返回集合中所有文档中 number 数组字段的不同值,如下:

# 查询 
sit_rs1:PRIMARY> db.user.distinct("number")
[
        {
                "n1" : 1,
                "n2" : 3
        },
        {
                "n1" : 1,
                "n2" : 8
        },
        {
                "n1" : 2,
                "n2" : 4
        },
        {
                "n1" : 2,
                "n2" : 6
        },
        {
                "n1" : 3,
                "n2" : 3
        },
        {
                "n1" : 3,
                "n2" : 6
        },
        {
                "n1" : 4,
                "n2" : 5
        },
        {
                "n1" : 4,
                "n2" : 6
        },
        {
                "n1" : 5,
                "n2" : 4
        },
        {
                "n1" : 5,
                "n2" : 5
        },
        {
                "n1" : 5,
                "n2" : 6
        },
        {
                "n1" : 6,
                "n2" : 6
        },
        {
                "n1" : 7,
                "n2" : 6
        },
        {
                "n1" : 7,
                "n2" : 8
        },
        {
                "n1" : 8,
                "n2" : 4
        },
        {
                "n1" : 8,
                "n2" : 5
        },
        {
                "n1" : 9,
                "n2" : 6
        }
]

另外,还可以指定查询条件,从查询条件中返回字段的不同值 , 如下:

# 查询 age 在 20、55、45 的文档 
sit_rs1:PRIMARY> db.user.find({"age":{$in: [20, 55, 45]}})
{ "_id" : ObjectId("64b8d2404b442dde59447cf1"), "name" : "user2", "age" : 20, "item" : { "A" : 112, "B" : 212 }, "number" : [ { "n1" : 1, "n2" : 3 }, { "n1" : 4, "n2" : 5 }, { "n1" : 7, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf4"), "name" : "user5", "age" : 55, "item" : { "A" : 112, "B" : 215 }, "number" : [ { "n1" : 7, "n2" : 8 }, { "n1" : 8, "n2" : 4 }, { "n1" : 4, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf6"), "name" : "user7", "age" : 45, "item" : { "A" : 116, "B" : 216 }, "number" : [ { "n1" : 6, "n2" : 6 }, { "n1" : 8, "n2" : 5 }, { "n1" : 7, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf3"), "name" : "user4", "age" : 45, "item" : { "A" : 111, "B" : 211 }, "number" : [ { "n1" : 9, "n2" : 6 }, { "n1" : 2, "n2" : 4 }, { "n1" : 3, "n2" : 6 } ] }
{ "_id" : ObjectId("64b8d2404b442dde59447cf5"), "name" : "user6", "age" : 55, "item" : { "A" : 115, "B" : 212 }, "number" : [ { "n1" : 5, "n2" : 5 }, { "n1" : 8, "n2" : 5 }, { "n1" : 7, "n2" : 6 } ] }

# 条例 age 查询条件的文档中,返回 item.A 中的不同值,这里的 112 只返回一条。
sit_rs1:PRIMARY> db.user.distinct("item.A", {"age":{$in: [20, 55, 45]}})
[ 111, 112, 115, 116 ]

使用排序规则,比如我们统计不同值时,是否要区分字每大小写等。如下:

  • strength: 2 二级比较。排序规则执行次要差异的比较,例如变音符号。也就是说,排序规则执行基本字符(主要差异)和变音符号(次要差异)的比较。基本字符之间的差异优先于次要差异。
  • strength: 3 三级比较。排序规则执行最多三级差异的比较,例如大小写和字母变体。也就是说,排序规则执行基本字符(主要差异)、变音符号(次要差异)以及大小写和变体(第三次差异)的比较。基本字符之间的差异优先于次要差异,次要差异又优先于第三次差异。
    这是默认级别。
sit_rs1:PRIMARY> db.myColl.insertMany([
... {_id: 1, color: "réd", letter: "A" },
... { _id: 2, color: "red", letter: "a" },
... { _id: 3, color: "rEd", letter: "a" },
... ])
{ "acknowledged" : true, "insertedIds" : [ 1, 2, 3 ] }

 
sit_rs1:PRIMARY> db.myColl.find()
{ "_id" : 1, "color" : "réd", "letter" : "A" }
{ "_id" : 2, "color" : "red", "letter" : "a" }
{ "_id" : 3, "color" : "rEd", "letter" : "a" }

# 二级比较:   执行基本字符(主要差异)和变音符号(次要差异)的比较
sit_rs1:PRIMARY> db.myColl.distinct( "color", {}, { collation: { locale: "zh", strength: 2 } } )
[ "réd", "red" ]

# 三级比较【默认级别】: 基本字符(主要差异)、变音符号(次要差异)以及大小写和变体(第三次差异)的比较
sit_rs1:PRIMARY> db.myColl.distinct( "color", {}, { collation: { locale: "zh", strength: 3 } } )
[ "réd", "red", "rEd" ]

estimatedDocumentCount

定义: db.collection.estimatedDocumentCount(options) , options 选修的。影响计数行为的额外选项。

  • 返回集合或视图中所有文档的计数。
  • estimatedDocumentCount() 不采用查询过滤器,而是使用元数据返回集合的计数。
  • db.collection.estimatedDocumentCount() 可能不准确。
  • 在分片集群上,生成的计数将无法正确过滤掉 孤立文档。

下面的例子使用 db.collection.estimatedDocumentCount() 检索 user 集合中所有文档的计数:文章来源地址https://www.toymoban.com/news/detail-601846.html

sit_rs1:PRIMARY> db.user.estimatedDocumentCount({})
9


sit_rs1:PRIMARY> db.myColl.estimatedDocumentCount(); 
3

总结

  • 通过一些单一目的聚合如 count, distinct 可以很方便统计数量,查找不同值,但也要注意他们的一些行为,比如在分片集群的使用限制、以及在事务中执行计数操作。
  • 要在事务内执行计数操作,请使用 $count 聚合阶段或 $group(带有 $sum表达式)聚合阶段。

到了这里,关于Mongodb 多文档聚合操作处理方法(单一聚合)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MongoDB聚合操作:$changeStream

    返回集合、数据库或整个群集上的 Change Stream 游标。必须在聚合管道的第一阶段使用。 allChangesForCluster 可选:设置Change Stream是否包括群集中的所有更改。可能只能在管理数据库中打开。 fullDocument 可选:指定 update 操作修改时,更改通知是否包含完整文档的副本。 default :更

    2024年01月23日
    浏览(29)
  • [Mongodb 5.0]聚合操作

     本文对应Aggregation Operations — MongoDB Manual    正文 此章节主要介绍了Aggregation Pipeline,其实就是将若干个聚合操作放在管道中进行执行,每一个聚合操作的结果作为下一个聚合操作的输入,每个聚合指令被称为一个stage。 在正式开始学习聚合操作前,请先按照下面的方式在你

    2024年02月12日
    浏览(37)
  • MongoDB聚合操作符:$acosh

    $acosh 操作符返回给定值的反双曲余弦。 $acosh 的可以接受解析为 1 到正无穷之间数字的表达式,即 1 = value = +∞ 。 $acosh 返回值以弧度为单位,使用 $radiansToDegrees 操作符可以把输出值由弧度转换为角度。 缺省情况下 $acosh 范围值为 double ,如果 expression 的值被解析为 128-bit d

    2024年02月19日
    浏览(28)
  • MongoDB聚合操作符:$addToSet

    $addToSet 返回一个无重复元素的数组,元素值是对每个分组文档执行表达式的结果。数组元素顺序未指定。 $addToSet 可以用于下列聚合阶段: $bucket $bucketAuto $group $setWindowFeilds { $addToSet: expression } 如果表达式的值是个数组, $addToSet 会把整个数组当成一个元素添加到返回的数组。

    2024年02月20日
    浏览(35)
  • MongoDB聚合操作符:$acos

    $acos 操作符返回一个值的反余弦。从MongoDB4.2版本开始支持。 $acos 接受任何可被解析为值在 -1 到 1 之间的表达式,即: -1 = value = 1 $acos 返回值以弧度为单位,使用 $radiansToDegrees 操作符可以把输出值由弧度转换为角度。 缺省情况下 $acos 范围值为 double ,如果 expression 的值被解

    2024年02月21日
    浏览(27)
  • MongoDB聚合操作符:$accumulator

    $accumulator 可以定义自定义累加器操作符。累加器是一种操作符,可在文档通过管道时保持其状态(如:总数、最大值、最小值和相关数据)。 $accumulator 操作符支持执行自定义的JavaScript函数,可以实现MongoDB查询语言不支持的行为。 $accumulator 支持下列阶段: $bucket $bucketAuto

    2024年02月19日
    浏览(45)
  • MongoDB文档存储与插入操作详解

    MongoDB是一种流行的NoSQL数据库系统,以其灵活的文档存储方式而备受关注。在MongoDB中,数据以文档的形式存储,文档类似于JSON格式,使用BSON(二进制JSON)进行编码。本文将详细介绍MongoDB的文档存储和插入操作,帮助读者理解MongoDB的核心概念。 在MongoDB中,文档是MongoDB的数

    2024年02月17日
    浏览(27)
  • MongoDB-数据库文档操作(1)

    任务描述 文档数据在 MongoDB 中的插入和更新。 相关知识 本文将向大家介绍文档数据在 MongoDB 中的基本操作。 文档的数据结构和 JSON 基本一样,所有存储在集合中的数据都是 BSON 格式。BSON 是一种类 JSON 的一种二进制形式的存储格式,简称: Binary JSON 。 本文将教你掌握:

    2024年01月17日
    浏览(34)
  • MongoDB-数据库文档操作(2)

    任务描述 文档数据在 MongoDB 中的查询和删除。 相关知识 本文将教你掌握: 查询文档命令; 删除文档命令。 查询文档 我们先插入文档到集合 stu1 : 然后查看 stu1 ,命令和结果如图1所示(因为我们没有设置 _id ,所以 MongoDB 会默认生成: 图 1 上述显示的文档格式不够整齐,

    2024年01月18日
    浏览(30)
  • Mongodb 对嵌套文档数组进行查询操作

    非嵌套文档的数组,数组由数字、字符串等元素组成。 以下方法对数组字段进行查询操作的示例,包括对数组匹配查询,元素的增、删、改操作,空数组、非空数组查询等。 连接到 mongodb 数据库, 创建集合 user, 批量插入如下测试数据 : 在指定数组上的使用相等条件,请

    2024年02月17日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包