Query a reference to an object stored in a document mongoDB - mongodb

I am wondering how exactly I would build query to filter based on the attributes of a stored document within a document using MongoDB.
Example:
My first collection is called Movies, it has a document as so:
_id: ObjectID("5d872b7f927f2538e4eefbf5")
mvNumb : "1"
Director : ObjectID("5d8abd243372eb2850ad71e7")
The second collection is called Director, and the director has the following fields:
_id: ObjectID("5d8abd243372eb2850ad71e7")
Name : "Sam"
What I am trying to do, is filter al my movies based on their director name. An ideal query would look like :
db.Movies.Find({"Director.Name : "Sam"})

Try;
db.directors.aggregate([
{
$match: {
Name: "Sam"
}
},
{
$lookup: {
from: "movies",
localField: "_id",
foreignField: "Director",
as: "movies"
}
},
{
$project: {
_id: 0,
movies: 1
}
}
])
You can first get the target director with Name using $match. Then find the movies that director is affiliated with using $lookup, which is essentially a join-like operation, that fetches all such movies, and puts them under a movies field. Then just project those fields only.
Check on mongoplayground

Related

How to update fields in a MongoDB collection if certain conditions met between two collections?

What am I doing?
So I am trying to update two fields in my MongoDB collection. The collection name is mydata and looks like this:
{
id: 123,
name: "John",
class: "A-100",
class_id: "", <-- Need to update this field,
class_type: "", <-- Need to update this field
}
What do I want to do?
I have another collection that is older, but it contains two fields that I need that I do not have in my current collection. But they both have the id field that corresponds. This is how it looks like the other collection:
{
id: 123,
name: "John",
class: "A-100",
class_id: 235, <-- Field That I need,
class_type: "Math" <-- Field That I need
}
What have I done so far?
I started an aggregate function that starts with a $lookup then $unwind then $match then $project. Looks like this:
db.mydata.aggregate([
{
$lookup: {
from: "old_collection",
localField: "id",
foreignField: "id",
as: "newData"
}
},
{
$unwind: "newData"
},
{
$match: {"class": "A-100"}
},
{
$project: {
_id: 0,
"id": "$newData.id",
"class_id": "$newData.class_id",
"class_type": "$newData.class_type"
}
},
Need help here to update mydata collection in the
fields that I pointed in the top
])
In summary
What I am trying to do is: If two objects from different collections have the same Id then pick the keys from the second object and update the keys in the first object.
Is there a way to do that in MongoDB?
Thanks.

How can I make query in mongoDB to get result from two collections with count boolean values

I am new in mongodb working on to develop chat application,
from two collections I want result with fields names like
_id,
username,
fname, lname,
isOnline,
updatedAt, count.
_id,username,fname,lname,isOnline and updatedAt comes under users collection and count which I have to obtain based on, _id(sender_id) and active_user(which I pass from function when user gets online, its receiverId) having isRead=false.
Users collection fields are,
Chat collection fields are,
here User devanggarach is online, I wanted to get list of users with count of unread messages(isRead=false)
db.users.aggregate(
[
{
$lookup:{
from:"chats",
localField : "_id",
foreignField : "receiverId",
as : "data"
}
},
{
$unwind:"$data"
},
{
$match:{
"data.isRead":false,
_id:{
$ne:ObjectId("ID")
}
}
},
{
$group:{
_id:"$_id",
username:{$first:"$username"},
fname:{$first:"$fname"},
lname:{$first:"$lname"},
isOnline:{$first:"$isOnline"},
updatedAt:{$first:"$updatedAt"},
unRead:{$sum:1}
}
},
{
$project:{
_id:1, username:1, fname:1, lname:1, isOnline:1, updatedAt:1, unRead:1
}
}
]
).pretty()

how to sort a mongoDB collection based on mapped value

a simple question (hopefully) to mongoDB users
i have 2 collection
collection A have a data with ID which the name (describing the ID) located in collection B.
i would like to query mongo to get all the Items from Collection A sorted ASC by the mapped name from Collection B.
TIA
well,
i found a simple solution for it:
db.createCollection("ColA")
db.createCollection("ColB")
db.ColA.insert({name:"Item1",priorityid:1})
db.ColA.insert({name:"Item2",priorityid:2})
db.ColA.insert({name:"Item3",priorityid:3})
db.ColA.insert({name:"Item4",priorityid:1})
db.ColA.insert({name:"Item5",priorityid:2})
ColA:
{"_id":"5fd7c79f774870001fa36872","name":"Item1","priorityid":1}
{"_id":"5fd7c7a9774870001fa36873","name":"Item2","priorityid":2}
{"_id":"5fd7c7bb774870001fa36875","name":"Item3","priorityid":3}
{"_id":"5fd7c7c8774870001fa36876","name":"Item4","priorityid":1}
{"_id":"5fd7c7d5774870001fa36877","name":"Item5","priorityid":2}
db.ColB.insert({name:"b_high",priorityid:1})
db.ColB.insert({name:"a_medium",priorityid:2})
db.ColB.insert({name:"c_low",priorityid:3})
ColB:
{"_id":"5fd7c810774870001fa3687b","name":"b_high","priorityid":1}
{"_id":"5fd7c842774870001fa3687c","name":"a_medium","priorityid":2}
{"_id":"5fd7c851774870001fa3687d","name":"c_low","priorityid":3}
Query:
db.ColA.aggregate([
{
$lookup:
{
from: "ColB",
localField: "priorityid",
foreignField: "priorityid",
as: "priorityname"
}
}, { $unwind:"$priorityname" }, {
$project:{
_id : 1,
name : 1,
priorityname : "$priorityname.name"
}
},{ $sort : { priorityname : 1 } }
])
result:
{"_id":"5fd7c7a9774870001fa36873","name":"Item2","priorityname":"a_medium"}
{"_id":"5fd7c7d5774870001fa36877","name":"Item5","priorityname":"a_medium"}
{"_id":"5fd7c79f774870001fa36872","name":"Item1","priorityname":"b_high"}
{"_id":"5fd7c7c8774870001fa36876","name":"Item4","priorityname":"b_high"}
{"_id":"5fd7c7bb774870001fa36875","name":"Item3","priorityname":"c_low"}

MongoDB create a filtered collection with 2 collections data

I have a mongo database that consist of huge github data (users, issues, repos, etc).
I want to create small collections from this big data.
I sorted "users" collection according to "followers" count of users.
Then I got the first 1000 users from this query.
db.getCollection("users").find({}).sort({followers:-1}).limit(1000).forEach(function(doc){
db.usersnew.insert(doc);});
There is another collection called "repos" that consists of info about users' repository. (user key field :"owner.id" )
I want to create a new filtered repos collection which consists only users who present in usersnew collection.
I tried to use $look_up but it works like join.
db.getCollection('reposnew').aggregate([{
$lookup:
{
from: "users",
localField: "owner:id",
foreignField : "id",
as: "filteredRepo"
}
}])
It creates users collection + repos in a one collection.
I want only filtered repos collection with specific users' data.
You're on the right track, you just need to add an $out stage.
db.getCollection('reposnew').aggregate([
{
$lookup:
{
from: "users",
localField: "owner.id",
foreignField : "id",
as: "filteredRepo"
}
},
{
$match: {
"filteredRepo.0": {$exists: true}
}
},
{
$project: {
filteredRepo: 0
}
},
{
$out: "newCollectionName"
}
])

How can I compare two fields in diffrent two collections in mongodb?

I am beginner in the MongoDB.
Right now, I am making one query by using mongo. Please look this and let me know is it possible? If it is possible, how can I do?
collection:students
[{id:a, name:a-name}, {id:b, name:b-name}, {id:c, name:c-name}]
collection:school
[{
name:schoolA,
students:[a,b,c]
}]
collection:room
[{
name:roomA,
students:[c,a]
}]
Expected result for roomA
{
name:roomA,
students:[
{id:a name:a-name isRoom:YES},
{id:b name:b-name isRoom:NO},
{id:c name:c-name isRoom:YES}
]
}
Not sure about the isRoom property, but to perform a join across collections, you'd have two basic options:
code it yourself, with multiple queries
use the aggregation pipeline with $lookup operator
As a quick example of $lookup, you can take a given room, unwind its students array (meaning separate out each student element into its own entity), and then look up the corresponding student id in the student collection.
Assuming a slight tweak to your room collection document:
[{
name:"roomA",
students:[ {studentId: "c"}, {studentId: "a"}]
}]
Something like:
db.room.aggregate([
{
$unwind: "$students"
},
{
$lookup:
{
from: "students",
localField: "studentid",
foreignField: "id",
as: "classroomStudents"
}
},
{
$project:
{ _id: 0, name : 1 , classroomStudents : 1 }
}
])
That would yield something like:
{
name:"roomA",
classroomStudents: [
{id:"a", name:"a-name"},
{id:"c", name:"c-name"}
]
}
Disclaimer: I haven't actually run this aggregation, so there may be a few slight issues. Just trying to give you an idea of how you'd go about solving this with $lookup.
More info on $lookup is here.