Use find operator to join multiple conditions in MongoDB
$lookup
Today, we will see how to concatenate multiple conditions using the operator
in MongoDB . In addition, we will explore some examples to demonstrate the use of $group
the stage and $unionWidth
the aggregation stage.
$lookup
Use the operator to connect multiple conditions
in MongoDB
If we have MongoDB 3.6 or higher, we can use $lookup
the aggregate pipeline
operator to concatenate multiple conditions.
For this purpose, we have two collections named users
and salaries
. You can also create it using the following command.
Sample code to create a collection:
> db.createCollection('users')
> db.createCollection('salaries')
users
Sample code to insert a document
into a collection:
> 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
Sample code to insert a document
into a collection:
> db.salaries.insertMany(
[
{
username: 'userone',
salary: 3000
},
{
username: 'usertwo',
salary: 5000
}
]
)
users
Display data of the collection:
> db.users.find().pretty()
Output:
{
"_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
Display data of the collection:
> db.salaries.find().pretty()
Output:
{
"_id" : ObjectId("628deb07c1e812eeeb311437"),
"username" : "userone",
"salary" : 3000
}
{
"_id" : ObjectId("628deb07c1e812eeeb311438"),
"username" : "usertwo",
"salary" : 5000
}
After creating the collection and inserting the documents, we can explore various scenarios to join multiple conditions. Let's $lookup
start with .
Using the $lookup
Aggregate pipeline
Operator
Sample code:
> 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()
Output:
{
"_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
}
]
}
Here, we get the documents that satisfy both conditions.
We get only the documents that satisfy these two conditions. You may have noticed usersalary
that is an array of elements, where each element is salaries
a document in the collection.
We can use $unwind
, $addFields
, and to get specific fields $project
from two collections ( users
and salaries
) and form a document as shown in the following example.
Sample code:
> 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()
Output:
{
"_id" : ObjectId("628deb40c1e812eeeb311439"),
"username" : "userone",
"salary" : 3000
}
{
"_id" : ObjectId("628deb40c1e812eeeb31143a"),
"username" : "usertwo",
"salary" : 5000
}
The purpose of using $unwind
the operator is to deconstruct an array field from the input documents into one output document for each element with the same name.
If there is only one element in the array, the $unwind
stage operator flattens the object, that is, the element itself. Concatenates the fields $addFields
in the object or array salary
to the root level of the document.
Before understanding the usage in the example given above, let us focus on $project
the reason for using the filter stage. If we don't use it $project
, we will get the document root level salary
fields and usersalary
objects, which is unnecessary.
This is where we use $project
the filtering stage and specify which fields should be included in the output.
If the project requirements restrict the use of $unwind
, $addFields
, $project
, we can use the alternative solution given below.
Sample code:
> 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()
Output:
{
"_id" : ObjectId("628deb07c1e812eeeb311437"),
"username" : "userone",
"salary" : 3000
}
{
"_id" : ObjectId("628deb07c1e812eeeb311438"),
"username" : "usertwo",
"salary" : 5000
}
We use let
fields (optional) to assign the value of the field to a variable. We pipeline
access these variables in the stage, where we specify pipeline
to execute on a different collection.
Note that we also use $match
the stage to take advantage of $expr
an evaluation query operator called , which compares the values of fields.
Additionally, $replaceRoot
being pipeline
the last aggregation stage in pipeline
, we merge the output of with the parts of the document using $mergeObjects
the operator .$lookup
$$ROOT
We have only used $and
the operator to connect the conditions. You can also use $or
the or two operators.
Create a new collection and use $group
the aggregation stage to join multiple conditions
Sample code:
> 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" }
}}
])
Output:
{ "_id" : { "username" : "userone" }, "salary" : [ 3000 ] }
{ "_id" : { "username" : "usertwo" }, "salary" : [ 5000 ] }
For this code example, we create a users_salaries
new collection named , merge two collections named users
and salaries
, and then insert the documents into the newly created collection. We then 用户名
group by to get the desired output.
We can also get the same output without creating a new collection (as shown above). To do this, we use $unionWith
the Aggregate stage, which performs a union of two collections.
Sample code:
> db.users.aggregate([
{ $set: { username: "$username" } },
{ $unionWith: {
coll: "salaries",
pipeline: [{ $set: { salary: "$salary" } }]
}},
{ $group: {
_id: { username: "$username"},
"salary": { "$push": "$salary" }
}}
])
Output:
{ "_id" : { "username" : "userone" }, "salary" : [ 3000 ] }
{ "_id" : { "username" : "usertwo" }, "salary" : [ 5000 ] }
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
Date comparison in MongoDB
Publish Date:2025/04/28 Views:170 Category:MongoDB
-
This MongoDB tutorial discusses the issue of returning Date-based queries. In addition, there is also a good tutorial on how to use Date Range queries in MongoDB. Using date ranges in MongoDB We will learn to write MongoDB date range querie
Find objects between two dates in MongoDB
Publish Date:2025/04/28 Views:95 Category:MongoDB
-
In this article, the problem of finding objects between two dates was briefly discussed. In addition, the operators $gte, $lte, $gt, and $lt used for this purpose were briefly explained in detail. Querying date ranges in MongoDB This sectio
Comparing Dates in MongoDB
Publish Date:2025/04/28 Views:115 Category:MongoDB
-
Date is a common field in most databases, and sometimes we need to find exact documents from a collection in MongoDB. For example, if we have a collection of orders, we might search for those documents before or after a specific date. In th
Convert string to date in MongoDB
Publish Date:2025/04/28 Views:162 Category:MongoDB
-
MongoDB is an excellent platform that is growing in popularity. Among the various features it offers, MongoDB also allows you to convert data from one type to another. This may seem like a complex function, but it is very simple to execute.
Building the MongoDB REST API
Publish Date:2025/04/28 Views:71 Category:MongoDB
-
MongoDB is a flexible and scalable document-oriented database system that is widely used for large-volume data storage. It uses documents and collections instead of the traditional rational database approach of using tables and rows. MongoD
Using ORM with MongoDB
Publish Date:2025/04/28 Views:118 Category:MongoDB
-
MongoDB introduces a NoSQL solution for data storage and management, consisting of documents represented in JSON style. Like other database systems, MongoDB can also use ORM. In this article, we will explain the concepts of ORM and general
Locking mechanism in MongoDB
Publish Date:2025/04/28 Views:96 Category:MongoDB
-
In database management systems, locking mechanisms ensure the consistency of the entire result. For example, if some writing process is in progress on the data, a read command cannot be executed at the same time. Database resources are lock
Unique Index in MongoDB
Publish Date:2025/04/28 Views:130 Category:MongoDB
-
In this article, you'll learn about unique indexes, including what they are and how to create them in MongoDB. Additionally, the process of making a user's email unique in MongoDB is briefly described. The contents of this article are as fo
Creating Indexes in MongoDB
Publish Date:2025/04/28 Views:179 Category:MongoDB
-
Indexes help resolve queries efficiently. Without indexes, MongoDB must iterate through every document in the collection to find the documents that match the query. It will waste time and require MongoDB to handle such information. Therefor