How can i find document into document arrray in mongodb - mongodb

I have one collection and that collection have array, and i wanna find that array ids which document ??
"_id" : ObjectId("5cde81d5f5622a42161c6065"),
"PhoneNumber" : "PhoneNumber",
"Nick" : "Nick",
"Token" : "Token1",
"MiniProfilePhoto" : "MiniPhoto",
"IsAndroid" : 1.0,
"ProfilePhotoId" : 0.0,
"ProfilePhotoKey" : 0.0,
"FriendMessages" : [
],
"Friends" : [
{
"FriendId" : ObjectId("5cde84a5f5622a42161c6068"),
"FriendState" : 2.0
},
{
"FriendId" : ObjectId("5cde740df5622a42161c6061"),
"FriendState" : 0.0
}
]
"_id" : ObjectId("5cde740df5622a42161c6061"),
"PhoneNumber" : "PhoneNumber1",
"Nick" : "Nick2",
"Token" : "Token4",
"MiniProfilePhoto" : "MiniPhoto5",
"IsAndroid" : 1.0,
"ProfilePhotoId" : 0.0,
"ProfilePhotoKey" : 0.0,
"FriendMessages" : [
],
"Friends" : [
{
"FriendId" : ObjectId("5cde81d5f5622a42161c6065"),
"FriendState" : 1.0
}
]
"_id" : ObjectId("5cde84a5f5622a42161c6068"),
"PhoneNumber" : "PhoneNumber",
"Nick" : "Nick",
"Token" : "Token",
"MiniProfilePhoto" : "MiniPhoto",
"IsAndroid" : 0.0,
"ProfilePhotoId" : 0.0,
"ProfilePhotoKey" : 0.0,
"FriendMessages" : [
],
"Friends" : [
{
"FriendId" : ObjectId("5cde81d5f5622a42161c6065"),
"FriendState" : 2.0
}
]
...
//that is my collection example, ObjectId("5cde81d5f5622a42161c6065")' s two friends, and that ids "FriendId" : ObjectId("5cde84a5f5622a42161c6068") and ObjectId("5cde740df5622a42161c6061") and i wanna find ObjectId("5cde84a5f5622a42161c6068") and ObjectId("5cde740df5622a42161c6061")'s tokens, how can i find my friends tokens? what is that aggregate?

Here is your aggregation Query,
let query = [
{
$match: {
_id: ObjectId("5cde81d5f5622a42161c6065")
}
},
{
$project: {
Friends: 1,
Token: 1
}
},
{
$unwind: "$Friends"
},
{
$lookup: {
from: "tets",
localField: "Friends.FriendId",
foreignField: "_id",
as: "fdata"
}
},
{
$unwind: { path: "$fdata", preserveNullAndEmptyArrays: true }
},
{
$group: {
_id: "$_id",
fdata: { $push: { Token: "$fdata.Token", _id: "$fdata._id" } }
}
}
]
db.collection.aggregate(query)
Output:
{
"_id" : ObjectId("5cde81d5f5622a42161c6065"),
"fdata" : [
{
"Token" : "Token",
"_id" : ObjectId("5cde84a5f5622a42161c6068")
},
{
"Token" : "Token4",
"_id" : ObjectId("5cde740df5622a42161c6061")
}
]
}

Related

mongoDB - how do i use projection and exclude a specific field with its value?

I have this array in a mongo document:
"labels" : [
{
"id" : "4b19c495-8c40-4c92-8c7d-ae9fb8defd20",
"labelCategory" : "Content",
"labelType" : "Content_label",
"code" : 5,
"labelName" : "HR Request Forms",
"trustValue" : 1.0,
"riskValue" : 0.0,
"sensitivity" : 0.2,
"concrete" : 0.8,
"threshold" : 2.0,
"abstracts" : [
"707babad-231f-82bb-014c-8506d3dc784e"
]
},
{
"id" : "707babad-231f-82bb-014c-8506d3dc784e",
"labelCategory" : "Content",
"labelType" : "Content_label",
"code" : 5,
"labelName" : "HR Information",
"trustValue" : 1.0,
"riskValue" : 0.0,
"sensitivity" : 0.2,
"concrete" : 0.2,
"threshold" : 2.0,
"abstracts" : []
},
{
"id" : "9cdce502-1dd9-4ef9-b78b-7f7c638490bf",
"labelCategory" : "Virtual",
"labelType" : "Virtual_label",
"code" : 1,
"labelName" : "Object Low Sensitive",
"trustValue" : 1.0,
"riskValue" : 0.0,
"sensitivity" : 0.0,
"concrete" : 0.0,
"threshold" : 0.0,
"abstracts" : []
}
],
For now all i have is this query:
db.getCollection('objects-89aafe20-780f-46ec-aaa0-a2d95bae542e').find(
{
objectCategory:"Content",
"labels":{
$elemMatch:{"labelCategory" : "Content", labelName:{$ne:"Other"}}
}
},
{objectName:1, _id:0, labels:{labelName:1}}
)
current output:
{
"labels" : [
{
"labelName" : "HR Request Forms"
},
{
"labelName" : "HR Information"
},
{
"labelName" : "Object Low Sensitive"
}
],
"objectName" : "hr-L1-4.xls"
}
I am trying to fetch only the "labelName" which related to an object which include "labelCategory" : "Content" (exclude the object that known as: "labelCategory" : "Virtual").
Any suggestions? Thanks.
$filter to iterate loop of labels and match both conditions, it will return filtered documents from labels array
$let to declare a labels variable and above $filter will be inside labels, $$labels in in refers declared variable, $$labels.labelName will return array of string
db.getCollection('objects-89aafe20-780f-46ec-aaa0-a2d95bae542e').find({
objectCategory: "Content",
labels: {
$elemMatch: {
labelCategory: "Content",
labelName: { $ne: "Other" }
}
}
},
{
_id: 0,
objectName: 1,
labels: {
$let: {
vars: {
labels: {
$filter: {
input: "$labels",
cond: {
$and: [
{ $eq: ["$$this.labelCategory", "Content"] },
{ $ne: ["$$this.labelName", "Other"] }
]
}
}
}
},
in: "$$labels.labelName"
}
}
})
Playground

MongoDB - $match based on another field value

I want to get results like simple inner join from SQL, for get all accounts of the same id_customer.
I almost do this, but I get something like left join, and I don't now how to filer the result of query.
query:
db.customer.aggregate([
{
$match: {
"LOAN.AMOUNT": { $gte: 41000 }
}
},
{
$lookup: {
from: "department",
localField: "ID",
foreignField: "ACCOUNT.ID_CUSTOMER",
as: "customer"
}
},
{ $match: { "myArray": { $ne: [] } } },
{
$unwind: {
path: "$customer",
preserveNullAndEmptyArrays: false
}
}
,
{
$unwind: "$customer.ACCOUNT"
},
{
$match: {
"customer.ACCOUNT.ID_CUSTOMER": "$ID"
}
},
])
actual result:
empty
expected result:
{
"_id" : ObjectId("5dfccc28d29876c2988c7c05"),
"ID" : 4.0,
"SECOND_NAME" : "abc",
"FIRST_NAME" : "abc",
"ID_DISCOUNT" : {
"ID" : 3.0,
"TITLE" : "abc",
"AMOUNT" : 5.0
},
"LOAN" : {
"ID" : 4.0,
"AMOUNT" : 42750.0
},
"customer" : {
"_id" : ObjectId("5dfb7f8f5861584bbaedf718"),
"ID" : 1.0,
"TITLE" : "abc",
"ADDRESS" : "abc",
"CITY" : "abc",
"ACCOUNT" : {
"ID" : 10.0,
"ID_CUSTOMER" : 4.0,
"DATE_OPEN" : "2019-09-24 21:03:44"
}
}
}
{
"_id" : ObjectId("5dfccc28d29876c2988c7c05"),
"ID" : 4.0,
"SECOND_NAME" : "abc",
"FIRST_NAME" : "abc ",
"ID_DISCOUNT" : {
"ID" : 3.0,
"TITLE" : "abc",
"AMOUNT" : 5.0
},
"LOAN" : {
"ID" : 4.0,
"AMOUNT" : 42750.0
},
"customer" : {
"_id" : ObjectId("5dfb7f8f5861584bbaedf718"),
"ID" : 1.0,
"TITLE" : "abc",
"ADDRESS" : "abc",
"CITY" : "abc",
"ACCOUNT" : {
"ID" : 11.0,
"ID_CUSTOMER" : 4.0,
"DATE_OPEN" : "2019-08-23 21:03:44"
}
}
}
List of all account with the same id_customer, but
$match: {
"customer.ACCOUNT.ID_CUSTOMER": "$ID"
}
not doing what I want to do.
I found the solution: use $expr operator
db.customer.aggregate([
{
$match: {
"LOAN.AMOUNT": { $gte: 41000 }
}
},
{
$lookup: {
from: "department",
localField: "ID",
foreignField: "ACCOUNT.ID_CUSTOMER",
as: "customer"
}
},
{ $match: { "myArray": { $ne: [] } } },
{
$unwind: {
path: "$customer",
preserveNullAndEmptyArrays: false
}
}
,
{
$unwind: "$customer.ACCOUNT"
},
{ $match: { $expr: { $eq: ["$customer.ACCOUNT.ID_CUSTOMER", "$ID"] } } },
])

What wrong with my mongo query to get a specific by nest document?

{
"_id" : ObjectId("5dbdacc28cffef0b94580dbd"),
"owner" : {
"image" : "https://lh3.googleusercontent.com/a-/AAuE7mCpG2jzbEdffPgdeVWnkBKwyzCCwEB1HMbU1LAVAg=s50",
"fullname" : "soeng kanel",
"userID" : "5da85558886aee13e4e7f044"
},
"image" : "soeng kanel-1572711618984.png",
"body" : "sdadadasdsadadas sds",
"date" : ISODate("2019-11-02T16:20:05.558Z"),
"comments" : [
{
"user" : "5da85558886aee13e4e7f044",
"fullname" : "soeng kanel",
"username" : "",
"comment" : "sdsfdsfdsfds",
"_id" : ObjectId("5dbdacc78cffef0b94580dbf"),
"replies" : [
{
"likes" : [
"5da85558886aee13e4e7f044"
],
"date" : ISODate("2019-11-02T16:20:05.558Z"),
"_id" : ObjectId("5dbdacd78cffef0b94580dc0"),
"reply" : "r1111111",
"username" : "",
"fullname" : "soeng kanel",
"user" : "5da85558886aee13e4e7f044"
},
{
"likes" : [],
"date" : ISODate("2019-11-02T16:20:05.558Z"),
"_id" : ObjectId("5dbdacdb8cffef0b94580dc1"),
"reply" : "r222222",
"username" : "",
"fullname" : "soeng kanel",
"user" : "5da85558886aee13e4e7f044"
},
{
"likes" : [],
"date" : ISODate("2019-11-03T03:04:23.528Z"),
"_id" : ObjectId("5dbe4749fa751f05afcc1bd6"),
"reply" : "33333333",
"username" : "",
"fullname" : "soeng kanel",
"user" : "5da85558886aee13e4e7f044"
}
],
"date" : ISODate("2019-11-02T16:20:05.558Z"),
"likes" : []
}
],
"likes" : [
"5da85558886aee13e4e7f044"
],
"project" : {},
"__v" : 2
}
My query is
db.getCollection("posts").aggregate([
{ $match: {_id: ObjectId("5dbdacc28cffef0b94580dbd"), "comments._id": ObjectId("5dbdacc78cffef0b94580dbf") }},
{ $unwind: "$comments"},
{ $match: { "comments._id": ObjectId("5dbdacc78cffef0b94580dbf")}},
{ $project: {"replies": "$comments.replies", _id: 0}},
{ $match: { "replies._id": ObjectId("5dbdacd78cffef0b94580dc0")}},
{ $project: {"likes": "$replies.likes", _id: 0}},
])
With this query I get 3 elements ,
{
"likes" : [
[
"5da85558886aee13e4e7f044"
],
[],
[]
]
}
That is not what I want, what I want is to get by specific
replies by this _id 5dbdacd78cffef0b94580dc0.
And My expectation
{
"likes" : [
[
"5da85558886aee13e4e7f044"
]
]
}
Try using $unwind on replies before you $match stage on replies.
db.collection.aggregate([
{
$match: {
_id: ObjectId("5dbdacc28cffef0b94580dbd"),
"comments._id": ObjectId("5dbdacc78cffef0b94580dbf")
}
},
{
$unwind: {
path: "$comments",
preserveNullAndEmptyArrays: false
}
},
{
$match: {
"comments._id": ObjectId("5dbdacc78cffef0b94580dbf")
}
},
{
$project: {
"replies": "$comments.replies",
_id: 0
}
},
{
$unwind: {
path: "$replies",
preserveNullAndEmptyArrays: false
}
},
{
$match: {
"replies._id": ObjectId("5dbdacd78cffef0b94580dc0")
}
},
{
$project: {
"likes": "$replies.likes"
}
}
])
Above query produce output in the following fashion:
[
{
"likes": [
"5da85558886aee13e4e7f044"
]
}
]
I hope that's okay.

count of $lookup result mongodb

Using mongodb with NodeJS driver
I have 2 collections. One for department and other for students.
Sample data for Deparmtent.
{
"_id" : ObjectId("5a24d20590d3d12155f3094e"), "name" : "CSE", "hod" :
"abc",
"students" : [
ObjectId("5a2129172c3e542acb78c1f5"),
ObjectId("5a2129172c3e542acb78c1f7"),
ObjectId("5a2129172c3e542acb78c1f9"),
ObjectId("5a2129172c3e542acb78c1fb")
]
}
{
"_id" : ObjectId("5a24d20590d3d12155f3094f"),
"name" : "IT",
"hod" : "xyz", ,
"students" : [
ObjectId("5a2129172c3e542acb78c1f6"),
ObjectId("5a2129172c3e542acb78c1f8"),
ObjectId("5a2129172c3e542acb78c1fa"),
ObjectId("5a2129172c3e542acb78c1fc")
]
}
and sample data for Students
{
"_id" : ObjectId("5a2129172c3e542acb78c1f4"),
"rollNumber" : 11,
"name" : "Thor",
"branch" : ObjectId("5a24d20590d3d12155f3094e"),
}
Here is the query:
aggregate([
{$lookup:
{ from: "students",
localField: "_id",
foreignField: "branch",
as: "studentData"
}
}
])
Output of the query
[
{ _id: 5a24d20590d3d12155f3094e,
name: 'CSE',
hod: 'abc',
studentData: [ [Object], [Object], [Object], [Object], [Object] ]
},
{ _id: 5a24d20590d3d12155f3094f,
name: 'IT',
hod: 'xyz',
studentData: [ [Object], [Object], [Object], [Object] ] }
]
I have two questions
How to print complete student data.
How to get the count of studentData for each Department
To get complete student data you can do something like
db.student.aggregate(
[
{
$lookup:
{
from:"department",
localField:"branch",
foreignField:"_id",
as:"branch"
}
}
]
)
This will give you something like this:
{
"_id" : 1.0,
"rollNumber" : 110.0,
"name" : "Thor",
"branch" : [
{
"_id" : 1.0,
"name" : "CSE",
"hod" : "abc"
}
]
}
To get the count of studentData for each Department
db.getCollection('student').aggregate(
[
{
$lookup:
{
from:"department",
localField:"branch",
foreignField:"_id",
as:"branch"
}
},
{
$group:
{
_id:"$branch",
"numOfStudent":{$sum:1},
"listOfStudents":{$push:"$name"}
}
}
]
)
This will give you something like this:
{
"_id" : [
{
"_id" : 2.0,
"name" : "IT",
"hod" : "xyz"
}
],
"numOfStudent" : 1.0,
"listOfStudents" : [
"Ironman2"
]
}
{
"_id" : [
{
"_id" : 1.0,
"name" : "CSE",
"hod" : "abc"
}
],
"numOfStudent" : 3.0,
"listOfStudents" : [
"Thor",
"Ironman",
"Ironman3"
]
}
You can change $push:$name to $push:$_id If you want to store the Ids of students and not their names.
EDIT
Get similar result using "Departments" collection:
db.department.aggregate([
{
$lookup:
{
from:"student",
localField:"students",
foreignField:"_id",
as:"studentsDetails"
}
},
{
$project:{
_id:0,
name:"$name",
hod:"$hod",
numOfStudents:{$size:"$studentsDetails"},
students:"$studentsDetails"
}
}
])
This will give you something like this:
{
"name" : "CSE",
"hod" : "abc",
"numOfStudents" : 2,
"students" : [
{
"_id" : 1.0,
"rollNumber" : 110.0,
"name" : "Thor",
"branch" : 1.0
},
{
"_id" : 3.0,
"rollNumber" : 111.0,
"name" : "Ironman2",
"branch" : 2.0
}
]
}
Your $lookup is completely fine. To add a count of students to your output data, you can use $addFields.
Add this to your aggregation:
{ $addFields: {studentCount: {$size: "$studentData"}}}
}
So, your query should be something like this:
aggregate([
{$lookup:
{ from: "students",
localField: "_id",
foreignField: "branch", as: "studentData"
}
}, { $addFields: {studentCount: {$size: "$studentData"}}
}
])

Aggregate result group objects

Where I arrived was this I needed to put the user data on the athele:
{
"_id" : ObjectId("5963c6aa1aaf2c1c702ea86f"),
"updatedAt" : ISODate("2017-07-10T18:25:46.941+0000"),
"createdAt" : ISODate("2017-07-10T18:25:46.933+0000"),
"name" : "athleta01",
"nickname" : "01",
"email" : "aaaa#terra.com.br",
"birthday" : ISODate("1986-09-15T03:00:00.000+0000"),
"gender" : "0",
"disable" : false,
"deletedAt" : false,
"profile" : [
{
"departament" : ObjectId("5963c6281aaf2c1c702ea86c"),
"profession" : "athlete",
"_id" : ObjectId("5963c6aa1aaf2c1c702ea870")
}
],
"photo" : null,
"__v" : NumberInt(0)
}
doc Athlete:
{
"_id" : ObjectId("5963c6aa1aaf2c1c702ea871"),
"updatedAt" : ISODate("2017-07-10T19:53:08.285+0000"),
"createdAt" : ISODate("2017-07-10T18:25:46.948+0000"),
"position" : "atacante",
"shirt" : NumberInt(15),
"document" : "87956421345",
"weight" : "10.5",
"height" : "2.73",
"profileId" : ObjectId("5963c6aa1aaf2c1c702ea870"),
"disable" : false,
"deletedAt" : false,
"device" : {
"activityLevel" : "vai atuazliar",
"maxHeartRate" : NumberInt(45),
"reposeHeartRate" : NumberInt(90),
"codSensor" : "1a2s4e1s"
},
"__v" : NumberInt(0)
}
Already tried to make the exit with the project and to set up a group also I did not have the result that I expected. I think I'm missing out on some point.
db.users.aggregate(
[
{
$match: {
"profile.departament" : ObjectId("5963c6281aaf2c1c702ea86c")
}
},
{
$lookup: {
"from" : "institution",
"localField" : "profile.departament",
"foreignField" : "departament._id",
"as" : "user_departament"
}
},
{
$lookup: {
"from" : "athlete",
"localField" : "profile._id",
"foreignField" : "profileId",
"as" : "athlete_departament"
}
},
{
$unwind: {
path: "$athlete_departament",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: "users",
localField: "athlete_departament.profileId",
foreignField: "profile._id",
as: "username",
}
},
{
$group: {
_id: { name: "$user_departament.name", cnpj: "$user_departament.cnpj", photo: "$user_departament.photo"},
departaments: {
$push : "$user_departament.departament"
},
athletes: {
$push : '$athlete_departament',
}
}
},
{$unwind : "$departaments"},
{$unwind : "$departaments"},
{$unwind : "$_id.name"},
{$unwind : "$_id.cnpj"},
{$unwind : "$_id.photo"},
{$unwind : "$athletes"},
{$unwind : "$athletes"},
{
$group : {
_id : "$_id",
departaments : {$addToSet : "$departaments"},
athletes : {$addToSet : "$athletes"}
}
},
{ "$project": {
//_id : { name: "$_id", departaments: { $concatArrays: [ {$arrayElemAt: [ "$departaments", 0 ]}, "$profiles", "$athletes" ] }}
_id : { institution: "$_id", departaments: { info: "$departaments", profiles: "$profiles", athletes: { username: "$username", athlete: "$athletes" }, }}
//_id : { name: "$_id", departaments: { "departament": { $concatArrays: [ { $arrayElemAt: ["$departaments", 0]}, "$athletes" ] }}}
//_id : { name: "$_id", departaments: { $concatArrays: [ {$arrayElemAt: [ "$departaments", 0 ]}, "$profiles", "$athletes" ] }}
}},
{$unwind : "$_id.departaments.info"},
{$unwind : "$_id.departaments.info"}
]);