学习MongoDB中的组操作符

344 阅读2分钟

MongoDB中的群组操作员

组运算符(也称为累加器运算符)是MongoDB语言中的一个重要运算符,因为它有助于执行数据的各种转换。它是MongoDB中聚合的一部分。MongoDB是一个开源的NoSQL数据库管理程序。

NoSQL是传统关系型数据库的替代品。在处理大量分布式数据集时,NoSQL数据库相当有用。MongoDB是一个可以管理面向文档的信息、存储或检索信息的工具。

在这篇文章中,我们将通过一些例子来学习$group操作符。

前提条件

在我们开始之前,请确保你有以下条件。

  • 在你的系统中安装了MongoDB。

  • 必须有一些关于MongoDB及其shell命令的知识。

聚合

聚合是一种操作,它处理数据以给出一个计算的结果。聚合操作将来自多个文档的值组合在一起,并可以对组合后的数据执行各种操作,以返回一个单一的结果。它涉及到一些阶段或管道,通过这些阶段或管道对数据进行处理以产生一个综合结果。

管道是对数据进行处理的阶段,从技术上讲是根据所提供的标准进行转换。每条管道都是独立的,接收前一个阶段的数据。请记住,第一条管道将直接接触数据本身,而不是其转换后的版本,它可以利用索引的优势。

什么是$group操作符?

顾名思义,$group 操作符通过一些指定的表达式对类似的数据进行分组,并将其合并为一个结果或文档。

假设一个数据库中有15个人,他们都有类似的爱好。如果我们想计算所有那些有共同爱好的人,那么$group 操作符是这种任务的一个优雅解决方案。

让我们看一下它的语法。

{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }

输出文档中的_id 字段包含了不同的按键分组。输出文档也可以包含计算字段,这些字段持有一些由$group的_id 字段分组的累加器表达式的值。

这里的_id 字段将采取那些你想对文档进行分组的字段。这里必须使用_id

$group运算符并不从数据库中删除数据。它只是根据传递到_id 字段的字段,将多个文档聚合成一个文档。

需要记住的重要一点是

  • 它不能与LogReduce 操作符一起使用。

  • 当解析和命名(别名)字段时,避免使用分组函数或其他运算符的名称作为字段名。

  • 当使用count,或任何分组函数时,记得在字段名前包括下划线(sort by _count)。

  • 多个聚合函数可以在同一行,但你不能在查询的同一行包括其他函数,如数学函数。

例子

现在,让我们看一个例子。这些代码片断应该在mongo shell中运行。

让我们创建一个数据库。

use review 

现在,让我们创建一个名为person 的集合,并使用insertMany() 函数在该集合中插入多个文档,如。

db.person.insertMany([
    {
        "_id" : ObjectId("5ffb0dd58591ec5a52d2afbd"),
        "name" : "Harit Joshi",
        "age" : 18,
        "gender" : "Male",
        "hobbies" : [
                "sports",
                "cooking",
                "gaming"
        ]
    },
    {
        "_id" : ObjectId("5ffb0dd58591ec5a52d2afbe"),
        "name" : "Maria Swartz",
        "age" : 27,
        "gender" : "Female",
        "hobbies" : [
                "sports",
                "swimming",
                "gaming"
        ]
    },
    {
        "_id" : ObjectId("5ffb0dd58591ec5a52d2afbf"),
        "name" : "Billy Marton",
        "age" : 34,
        "gender" : "Male",
        "hobbies" : [
                "singing",
                "cooking",
                "jogging"
        ]
    }
])

现在我们在集合中已经有了一些文档,让我们使用$group ,来查找集合中的男性和女性的数量。

要做到这一点,我们必须在集合中使用aggregate() ,该函数需要一个管道数组或阶段,集合中的数据将通过这些管道进行转换。由于我们对数据分组感兴趣,我们必须使用$group 操作符和一个累加器操作符。

你必须提供一个键,用来保存累加器运算符的结果。在这个例子中,我们使用totalPerson 作为键,这将帮助我们对数据进行汇总。

aggregate() 函数的Synatx。

db.<name of the collection>.aggregate([ 'array of pipelines' ])

注意:aggregate() 函数中的管道或阶段将总是以文件格式出现。

现在应用我们上面学到的逻辑和语法,查询将看起来像。

db.person.aggregate([ { $group: {_id: {gender: "$gender"}, totalPeople: {$sum: 1}} } ]).pretty()

输出。

{ "_id" : { "gender" : "Female" }, "totalPeople" : 1 }
{ "_id" : { "gender" : "Male" }, "totalPeople" : 2 }

正如你所看到的,_id 字段将保存你对数据进行分组的字段或标准,totalPeople 是保存累加器运算符(即$sum )结果的键。

$sum 操作符将返回所有数字值的总和,这些数字值是对一组共享相同分组键的文件中的每个文件应用指定表达式的结果。

为了使$group 操作符发挥作用,你必须使用一个累加器操作符,如$sum,$avg,$max, 或$push 。因为该操作符会产生一个基于分组表达式的综合结果。

让我们看一下另一个用例。假设我们对有类似爱好的人的数量感兴趣。为了达到这个目的,我们应该通过使用$unwind 操作符使每个爱好成为一个独立的顶层字段。

$unwind 操作符将从你使用该操作符的数组中一个一个地拉出每个值,并将其以单个键值对的形式分配给持有该数组的关键。

这使得查询数据库中的数组和数据更加灵活。然后,我们必须做与第一个例子相同的操作,因为爱好不是一个数组,而是一个键值形式的顶层字段,应用$group 操作符将使它更容易。

db.person.aggregate([ {$unwind: "$hobbies"}, { $group: {_id: {hobby: "$hobbies"}, totalPeople: {$sum: 1}} } ]).pretty() 

输出。

{ "_id" : { "hobby" : "jogging" }, "totalPeople" : 1 }
{ "_id" : { "hobby" : "singing" }, "totalPeople" : 1 }
{ "_id" : { "hobby" : "cooking" }, "totalPeople" : 2 }
{ "_id" : { "hobby" : "gaming" }, "totalPeople" : 2 }
{ "_id" : { "hobby" : "sports" }, "totalPeople" : 2 }
{ "_id" : { "hobby" : "swimming" }, "totalPeople" : 1 }

$group操作符的应用。

  1. 每当我们需要像在我们的例子中那样找到有多少人适合在一个组中时,$group 操作符就会非常有用。

  2. 在我们想根据其他数据的一些重复出现来查看文件的情况下,它也可以发挥作用。

  3. 如果我们想创建一个与数据相关的类似实体的数组,并将其包含在我们的最终文件中,那么可以使用$group操作符。