迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 数据库 > MongoDB >

使用 MongoDB 将两个集合合并为一个集合

作者:迹忆客 最近更新:2023/03/17 浏览次数:

今天,我们将使用 $lookup 聚合阶段、pipeline$unwind 运算符、$project 过滤阶段和 MongoDB Compass 将两个集合合并为一个集合。

使用 MongoDB 将两个集合合并为一个集合

我们有不同的方法可以使用 MongoDB 将两个集合组合成一个集合。其中一些在下面给出,我们将在本教程中介绍。

对于上述所有场景,我们必须有一个包含两个集合(与 MySQL 中的表相同)的数据库,其中填充了文档(与 MySQL 中的记录相同)。我们使用以下查询完成了这项工作;你也可以这样做。

创建两个名为 usersInformationuserAddress 的集合,它们位于 users 数据库中。此外,使用以下文档填充它们。

创建数据库和集合:

> use users
> db.createCollection('userInformation')
> db.createCollection('userAddress')

用两个文档填充 userInformation 集合:

> db.userInformation.insertMany(
    [
        {
            fullname: 'Mehvish Ashiq',
            age: 30,
            gender: 'Female',
            nationality: 'Pakistani'
        },
        {
            fullname: 'James Daniel',
            age: 45,
            sex: 'male',
            nationality: 'Canadian'
        }
    ]
)

用两个文档填充 userAddress 集合:

> db.userAddress.insertMany(
    [
        {
            fullname: 'Mehvish Ashiq',
            block_number: 22,
            street: 'Johar Town Street',
            city: 'Lahore'
        },
        {
            fullname: 'James Daniel',
            block_number: 30,
            street: 'Saint-Denis Street',
            city: 'Montreal'
        }
    ]
)

我们使用 insertMany() 函数插入多个文档。现在,我们可以使用下面的命令来查看两个集合的数据。

在下面的代码片段中,pretty() 方法显示了干净且格式化的输出,这在 shell 上很容易理解。

显示来自 userInformation 的文档:

> db.userInformation.find().pretty()

输出:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani"
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian"
}

显示来自 userAddress 的文档:

> db.userAddress.find().pretty()

输出:

{
        "_id" : ObjectId("628bc4ae5c544feccff5a568"),
        "fullname" : "Mehvish Ashiq",
        "block_number" : 22,
        "street" : "Johar Town Street",
        "city" : "Lahore"
}
{
        "_id" : ObjectId("628bc4ae5c544feccff5a569"),
        "fullname" : "James Daniel",
        "block_number" : 30,
        "street" : "Saint-Denis Street",
        "city" : "Montreal"
}

两个集合必须在同一个数据库中才能使用 $lookup 聚合阶段。一旦两个集合都准备好了,我们可以根据我们的场景使用各种查询来连接两个集合的数据。

使用 $lookup 聚合阶段将两个集合合二为一

示例代码:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    }
]).pretty();

输出:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani",
        "address" : [
                {
                        "_id" : ObjectId("628bc4ae5c544feccff5a568"),
                        "fullname" : "Mehvish Ashiq",
                        "block_number" : 22,
                        "street" : "Johar Town Street",
                        "city" : "Lahore"
                }
        ]
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian",
        "address" : [
                {
                        "_id" : ObjectId("628bc4ae5c544feccff5a569"),
                        "fullname" : "James Daniel",
                        "block_number" : 30,
                        "street" : "Saint-Denis Street",
                        "city" : "Montreal"
                }
        ]
}

在 MongoDB 数据库中,$lookup 聚合阶段执行与其他集合的左外连接,并从连接的文档中过滤信息(数据)。例如,我们使用查询来获取所有用户的信息及其地址。

$lookup 函数接受四个字段。首先是 from 字段,我们在其中指定应该与另一个集合连接的集合。

第二个是 localField 字段。它是 from 字段中指定的集合的输入文档的属性(字段)之一。

它用于对集合文档中的 localFieldforeignField 执行匹配。

类似地,名为 foreignField 的第三个字段也对集合文档中的 foreignFieldlocalField 执行相等匹配。

我们为第四个字段 as 写下新数组的名称。有关 $lookup 聚合阶段的说明,请参见以下说明。

使用 mongodb 将两个集合合并为一个集合 - 查找阶段解释

使用 pipeline 运算符根据指定条件将两个集合合并为一个

示例代码:

> db.userInformation.aggregate([{
    $lookup:{
        from: 'userAddress',
        let: {full_name: '$fullname'},
        pipeline: [{
            $match: {
                $expr: {
                    $eq: ['$fullname', '$$full_name']
                }
             }
       }],
       as: 'addressInfo'
    }
}]).pretty()

输出:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani",
        "addressInfo" : [
                {
                        "_id" : ObjectId("628bc4ae5c544feccff5a568"),
                        "fullname" : "Mehvish Ashiq",
                        "block_number" : 22,
                        "street" : "Johar Town Street",
                        "city" : "Lahore"
                }
        ]
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian",
        "addressInfo" : [
                {
                        "_id" : ObjectId("628bc4ae5c544feccff5a569"),
                        "fullname" : "James Daniel",
                        "block_number" : 30,
                        "street" : "Saint-Denis Street",
                        "city" : "Montreal"
                }
        ]
}

当我们想要基于特定条件连接两个集合时,我们可以使用带有 $lookuppipeline 运算符(就像我们在 MySQL 中使用 WHERE 子句一样)。

例如,我们正在加入来自 userAddressfullname 等于 userInformation 中的 fullname 的集合。

在附加到结果文档之前使用 $unwind 运算符来平面数组

示例代码:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    },
    {
       $unwind: '$address'
    }
]).pretty();

输出:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani",
        "address" : {
                "_id" : ObjectId("628bc4ae5c544feccff5a568"),
                "fullname" : "Mehvish Ashiq",
                "block_number" : 22,
                "street" : "Johar Town Street",
                "city" : "Lahore"
        }
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian",
        "address" : {
                "_id" : ObjectId("628bc4ae5c544feccff5a569"),
                "fullname" : "James Daniel",
                "block_number" : 30,
                "street" : "Saint-Denis Street",
                "city" : "Montreal"
        }
}

$unwind 运算符什么也不做,只是在将数组附加到结果文档之前将其展平。 $unwind 运算符的根本区别在于它将具有单个元素的数组转换为扁平对象,即元素本身。

请记住,此元素的名称不会更改。当元素为数组形式时,它与以前相同。

使用和不使用 $unwind 运算符执行上述查询并观察 address 字段。

在聚合查询中使用 $project 过滤器阶段将两个集合合二为一

在使用 $project 加入集合之前,让我们了解它的重要性。例如,如果我们不想将名为 userAddress 的整个集合与 userInformation 连接起来,我们只希望连接 citystreet 字段。

在这种情况下,我们需要使用 $addFields 阶段。我们使用此阶段将数组/对象中的任何字段或多个字段加入/分配到文档的根级别。

因此,我们执行以下查询以从 userAddress 集合中检索 citystreet

示例代码:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    },
    {
       $unwind: '$address'
    },
    {
       $addFields: {
           street: '$address.street',
           city: '$address.city'
       }
    }
]).pretty();

输出:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani",
        "address" : {
                "_id" : ObjectId("628bc4ae5c544feccff5a568"),
                "fullname" : "Mehvish Ashiq",
                "block_number" : 22,
                "street" : "Johar Town Street",
                "city" : "Lahore"
        },
        "street" : "Johar Town Street",
        "city" : "Lahore"
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian",
        "address" : {
                "_id" : ObjectId("628bc4ae5c544feccff5a569"),
                "fullname" : "James Daniel",
                "block_number" : 30,
                "street" : "Saint-Denis Street",
                "city" : "Montreal"
        },
        "street" : "Saint-Denis Street",
        "city" : "Montreal"
}

仔细关注上面给出的输出。我们得到了街道城市吗?是的,我们在文档的根级别获得了 streetcity,但也有我们现在不需要的 address 对象。

这就是 $project 过滤阶段的用武之地。它指定我们应该在结果文档中包含哪些字段。

请参阅以下查询以获得更好的理解。

示例代码:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    },
    {
       $unwind: '$address'
    },
    {
       $addFields: {
           street: '$address.street',
           city: '$address.city'
       }
    },
    {
       $project: {
           fullname: 1,
           age: 1,
           gender: 1,
           street: 1,
           city: 1
       }
    }
]).pretty();

输出:

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "street" : "Johar Town Street",
        "city" : "Lahore"
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "street" : "Saint-Denis Street",
        "city" : "Montreal"
}

如你所见,我们现在没有 address 对象,但它的两个字段(streetcity)被分配给文档的根级别。

使用 Compass 连接两个集合(MongoDB 的图形界面)

使用图形界面进行聚合很容易。我们只需要在 $lookup 聚合阶段执行以下步骤。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

比较 MongoDB 中的字段

发布时间:2023/04/21 浏览次数:51 分类:MongoDB

在本文中,我们将了解如何比较 MongoDB 中的两个字段。 此外,我们将看到一个相关的示例和解释,以使主题更容易理解。

清除或删除 MongoDB 中的集合

发布时间:2023/04/21 浏览次数:147 分类:MongoDB

本篇文章将告诉大家如何删除 MongoDB 数据库中的集合以及删除 MongoDB 中的集合的不同方法。

MongoDB 截断集合

发布时间:2023/04/21 浏览次数:178 分类:MongoDB

可以根据需要选择两个选项之一来截断下面的集合。 在今天的文章中,我们将学习如何在 MongoDB 中截断集合。

删除 MongoDB 中的重复项

发布时间:2023/04/21 浏览次数:151 分类:MongoDB

在本文中,我们将了解如何删除 MongoDB 中的重复条目,并且我们还将看到一个带有适当解释的示例,以使主题更容易理解。

使用 NodeJS 检查 MongoDB 中是否存在集合

发布时间:2023/04/21 浏览次数:194 分类:MongoDB

在本文中,我们将检查 MongoDB 数据库中是否存在一个集合,并且我们还将查看与主题相关的示例,以使主题更容易理解。 为此,我们将使用 Node.js。

MongoDB 中的唯一索引

发布时间:2023/04/21 浏览次数:144 分类:MongoDB

在这篇教学文章中,您将了解唯一索引、它们是什么以及如何在 MongoDB 中使索引唯一。 此外,还简要详细地解释了使用户的电子邮件在 MongoDB 中唯一。

在 MongoDB 中创建索引

发布时间:2023/04/21 浏览次数:104 分类:MongoDB

索引有助于有效解决查询。 如果没有索引,MongoDB 必须遍历集合中的每个文档才能找到与查询匹配的文档。因此,在今天的文章中,我们将学习如何在 MongoDB 中创建索引。

MongoDB 中的稀疏索引

发布时间:2023/04/21 浏览次数:142 分类:MongoDB

在本文中,我们将讨论 MongoDB 中的稀疏索引。 此外,我们将提供一个相关示例并进行解释,以使该主题更容易理解。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便