迹忆客 专注技术分享

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

在 MongoDB 中使用查找运算符连接多个条件

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

今天,我们将了解如何在 MongoDB 中使用 $lookup 运算符连接多个条件。此外,我们还将探索一些示例来演示 $group 阶段和 $unionWidth 聚合阶段的使用。

在 MongoDB 中使用 $lookup 运算符连接多个条件

如果我们有 MongoDB 3.6 或更高版本,我们可以使用 $lookup 聚合 pipeline 运算符来连接多个条件。

为此,我们有两个名为 userssalaries 的集合。你也可以使用以下命令创建它。

创建集合的示例代码:

> db.createCollection('users')
> db.createCollection('salaries')

users 集合中插入文档的示例代码:

> db.users.insertMany(
    [
        {
            username: 'userone',
            age: 30,
            gender: 'Female',
            city: 'Lahore',
            country: 'Pakistan'
        },
        {
            username: 'usertwo',
            age: 35,
            gender: 'Male',
            city: 'Florida',
            country: 'United States'
        }
    ]
)

salaries 集合中插入文档的示例代码:

> db.salaries.insertMany(
    [
        {
            username: 'userone',
            salary: 3000
        },
        {
            username: 'usertwo',
            salary: 5000
        }
    ]
)

users 集合的显示数据:

> db.users.find().pretty()

输出:

{
        "_id" : ObjectId("628deb40c1e812eeeb311439"),
        "username" : "userone",
        "age" : 30,
        "gender" : "Female",
        "city" : "Lahore",
        "country" : "Pakistan"
}
{
        "_id" : ObjectId("628deb40c1e812eeeb31143a"),
        "username" : "usertwo",
        "age" : 35,
        "gender" : "Male",
        "city" : "Florida",
        "country" : "United States"
}

salaries 集合的显示数据:

> db.salaries.find().pretty()

输出:

{
        "_id" : ObjectId("628deb07c1e812eeeb311437"),
        "username" : "userone",
        "salary" : 3000
}
{
        "_id" : ObjectId("628deb07c1e812eeeb311438"),
        "username" : "usertwo",
        "salary" : 5000
}

创建集合并插入文档后,我们可以探索各种场景来加入多个条件。让我们从 $lookup 开始。

使用 $lookup 聚合 pipeline 运算符

示例代码:

> db.users.aggregate([
    {
        $lookup: {
            from: 'salaries',
            let: {
                user_name: '$username',
                user_salary: 3000
            },
            pipeline: [{
                $match: {
                    $expr: {
                        $and: [
                            { $eq: ['$username', '$$user_name'] },
                            { $gte: ['$salary','$$user_salary'] }
                        ]
                    }
                }
           }],
           as: 'usersalary'
        }
    }
]).pretty()

输出:

{
        "_id" : ObjectId("628deb40c1e812eeeb311439"),
        "username" : "userone",
        "age" : 30,
        "gender" : "Female",
        "city" : "Lahore",
        "country" : "Pakistan",
        "usersalary" : [
                {
                        "_id" : ObjectId("628deb07c1e812eeeb311437"),
                        "username" : "userone",
                        "salary" : 3000
                }
        ]
}
{
        "_id" : ObjectId("628deb40c1e812eeeb31143a"),
        "username" : "usertwo",
        "age" : 35,
        "gender" : "Male",
        "city" : "Florida",
        "country" : "United States",
        "usersalary" : [
                {
                        "_id" : ObjectId("628deb07c1e812eeeb311438"),
                        "username" : "usertwo",
                        "salary" : 5000
                }
        ]
}

在这里,我们得到满足两个条件的文档。

我们只得到满足这两个条件的文件。你可能已经注意到 usersalary 是一个元素数组,其中每个元素都是 salaries 集合的文档。

我们可以使用 $unwind$addFields$project 从两个集合(userssalaries)中获取特定字段并形成一个文档,如下例所示。

示例代码:

> db.users.aggregate([
    {
        $lookup: {
            from: 'salaries',
            let: {
                user_name: '$username',
                user_salary: 3000
            },
            pipeline: [{
                $match: {
                    $expr: {
                        $and: [
                            { $eq: ['$username', '$$user_name'] },
                            { $gte: ['$salary','$$user_salary'] }
                        ]
                    }
                }
           }],
           as: 'usersalary'
        }
    },
    {
        $unwind:'$usersalary'
    },
    {
        $addFields: {
            salary: '$usersalary.salary'
        }
    },
    {
       $project: {
           username: 1,
           salary: 1
       }
    }
]).pretty()

输出:

{
        "_id" : ObjectId("628deb40c1e812eeeb311439"),
        "username" : "userone",
        "salary" : 3000
}
{
        "_id" : ObjectId("628deb40c1e812eeeb31143a"),
        "username" : "usertwo",
        "salary" : 5000
}

使用 $unwind 运算符的目的是为每个具有相同名称的元素解构一个数组字段,从输入文档到输出一个文档。

如果数组中只有一个元素,则 $unwind 阶段运算符将对象展平,即元素本身。 $addFields 将对象或数组中的 salary 字段连接到文档的根级别。

在了解上面给出的示例中的用法之前,让我们先关注使用 $project 过滤器阶段的原因。如果我们不使用 $project,我们将获得文档根级别的 salary 字段和 usersalary 对象,这是不必要的。

这是我们使用 $project 过滤阶段并指定输出中应包含哪些字段的地方。

如果项目要求限制使用 $unwind$addFields$project,我们可以使用下面给出的替代解决方案。

示例代码:

> db.users.aggregate([
    {
        $lookup: {
            from: 'salaries',
            let: {
                user_name: '$username',
                user_salary: 3000
            },
            pipeline: [{
                $match: {
                    $expr: {
                        $and: [
                            { $eq: ['$username', '$$user_name'] },
                            { $gte: ['$salary','$$user_salary'] }
                        ]
                    }
                }
           }],
           as: 'usersalary'
        }
    },
       {
          $replaceRoot: {
             newRoot: {
                $mergeObjects:[
                   {
                      $arrayElemAt: [
                         "$usersalary", 0
                      ]
                   },
                   {
                      salary: "$$ROOT.salary"
                   }
                ]
             }
          }
       }
    ]
).pretty()

输出:

{
        "_id" : ObjectId("628deb07c1e812eeeb311437"),
        "username" : "userone",
        "salary" : 3000
}
{
        "_id" : ObjectId("628deb07c1e812eeeb311438"),
        "username" : "usertwo",
        "salary" : 5000
}

我们使用 let 字段(可选)将字段的值分配给变量。我们在 pipeline 阶段访问这些变量,我们指定 pipeline 在不同的集合上执行。

请注意,我们还使用 $match 阶段来利用名为 $expr 的评估查询运算符,它比较字段的值。

此外,$replaceRootpipeline 中的最后一个聚合 pipeline 阶段,我们使用 $mergeObjects 运算符将 $lookup 输出与 $$ROOT 文档的部分合并。

我们只使用了 $and 运算符来连接条件。你也可以使用 $or 或两个运算符。

创建新集合并使用 $group 聚合阶段加入多个条件

示例代码:

> db.users_salaries.insertMany(
    db.users.find({}, {"_id": 0})
    .toArray()
    .concat(db.salaries.find({}, {"_id": 0}).toArray())
)

db.users_salaries.aggregate([
    { "$group": {
        "_id": { "username": "$username" },
        "salary": { "$push": "$salary" }
    }}
])

输出:

{ "_id" : { "username" : "userone" }, "salary" : [ 3000 ] }
{ "_id" : { "username" : "usertwo" }, "salary" : [ 5000 ] }

对于这个代码示例,我们创建一个名为 users_salaries 的新集合,合并两个名为 userssalaries 的集合,然后将这些文档插入到新创建的集合中。然后,按用户名分组以获得所需的输出。

我们也可以在不创建新集合的情况下获得相同的输出(如上所示)。为此,我们使用 $unionWith 聚合阶段,它为两个集合执行联合。

示例代码:

> db.users.aggregate([
  { $set: { username: "$username" } },
  { $unionWith: {
    coll: "salaries",
    pipeline: [{ $set: { salary: "$salary" } }]
  }},
  { $group: {
    _id: { username: "$username"},
     "salary": { "$push": "$salary" }
  }}
])

输出:

{ "_id" : { "username" : "userone" }, "salary" : [ 3000 ] }
{ "_id" : { "username" : "usertwo" }, "salary" : [ 5000 ] }

转载请发邮件至 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

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便