Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to query by reference field in MongoDB?

I have two Mongo schemas:

User:

{
  _id: ObjectId,
  name: String,
  country: ObjectId // Reference to schema Country
}

Country:

{
  _id: ObjectId,
  name: String
}

I want to get all users who have the country name "VietNam".

What kind of query (only to the User schema) can I use for this case?

I want it to look like this SQL query:

SELECT * 
FROM User
JOIN Country 
ON User.country = Country._id 
WHERE Country.name = 'VietNam'
like image 391
Vũ Anh Dũng Avatar asked Oct 27 '25 21:10

Vũ Anh Dũng


2 Answers

You can use below aggregation with mongodb 3.6 and above

db.country.aggregate([
  { "$match": { "name": "VietNam" } },
  { "$lookup": {
    "from": Users.collection.name,
    "let": { "countryId": "$_id" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": [ "$country", "$$countryId" ] } } },
    ],
    "as": "users",
  }},
  { "$unwind": "$users" },
  { "$replaceRoot": { "newRoot": "$users" }}
])
like image 175
Ashh Avatar answered Oct 30 '25 10:10

Ashh


Unlike relational databases, this isn't something that Mongo is good at, and you should generally structure your schemas in a different way when you're using NoSQL. In this case, you could add a countryName field to the user collection (and perhaps an index on country) so that you can query {countryName: "Vietnam"}. (Instead of country-name, it'd likely make more sense to use the iso-2 country code)

If you do need to do a "join" you can use the $lookup operator in the aggregation pipeline -- just keep in mind that aggregations don't scale well and tend to be a little hard to write.

like image 40
willis Avatar answered Oct 30 '25 10:10

willis