I have three collections listings, listingsCollections and profile. I used aggregation on listingsCollections and matched collectionID from listings. I used another lookup to add profile info to listings. My lookup response is like this
{
//listingsCollections fields
collectionID: 'abc',
collectionName: 'xyz',
listings: [
{
// listings fields
type: 'free',
listingName: 'listing one',
// profile fields
ownerInfo: {
name: 'user 1'
}
},
{
type: 'free',
listingName: 'listing three',
ownerInfo: {
name: 'user 1'
}
},
{
type: 'paid',
listingName: 'listing two',
ownerInfo: {
name: 'user 1'
}
},
]
}
I want to calculate type with count and total listings count.I don't want to pass hard coded type values in $addFields
with $cond
.
This is the disired output i am looking for.Is there any way to achieve this
{
collectionID: 'abc',
collectionName: 'xyz',
listingCount: {
free: 2,
paid: 1
},
totalListings: 3,
listings: [
{
type: 'free',
listingName: 'listing one',
ownerInfo: {
name: 'user 1'
}
},
{
type: 'free',
listingName: 'listing three',
ownerInfo: {
name: 'user 1'
}
},
{
type: 'paid',
listingName: 'listing two',
ownerInfo: {
name: 'user 1'
}
},
]
}
To create an object with unique keys, we need to use $arrayToObject
+ $objectToArray
operators.
input:
[{"type": "free"}, {"type": "free"}, {"type": "paid"}]
--------------- $objectToArray --------------------
[{"k": "type", "v": "free"}, {"k": "type", "v": "free"}, {"k": "type", "v": "paid"}]
--------------- $arrayToObject --------------------
{"free": 2, "paid": 1} // since objects cannot have same key for twice
Try this one:
db.collection.aggregate([
{
$addFields: {
listingCount: {
$arrayToObject: {
$map: {
input: "$listings.type",
as: "type",
in: {
k: "$$type",
v: {
$size: {
$filter: {
input: "$listings.type",
cond: {
$eq: [
"$$this",
"$$type"
]
}
}
}
}
}
}
}
},
totalListings: {
$size: "$listings"
}
}
}
])