I have two mongo documents of the structure
links document
{
"_id": {
"$oid": "6002d2d627925c4194a15a94"
},
"visit_count": 20,
"password": null,
"password_protected": false,
"description": null,
"analytics": [
{
"$oid": "6002d568e9c7d24d34413492"
},
{
"$oid": "6002d612464785401824a782"
}
],
"alias": "g",
"short_url": "https://reduced.me/g",
"long_url": "https://google.com",
"created": {
"$date": "2021-01-16T11:49:42.517Z"
},
"__v": 2
}
analytics document
[
{
"_id": {
"$oid": "6002d568e9c7d24d34413492"
},
"os": {
"windows": true,
"linux": false,
"mac": false,
"android": false
},
"browser": {
"opera": false,
"ie": false,
"edge": false,
"safari": false,
"firefox": true,
"chrome": false
},
"details": {
"os": "Windows 10.0",
"browser": "Edge",
"version": "87.0.664.75",
"platform": "Microsoft Windows",
"source": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 Edg/87.0.664.75"
},
"__v": 0
},
{
"_id": {
"$oid": "6002d612464785401824a782"
},
"os": {
"windows": true,
"linux": false,
"mac": false,
"android": false
},
"browser": {
"opera": false,
"ie": false,
"edge": true,
"safari": false,
"firefox": false,
"chrome": false
},
"details": {
"os": "Windows 10.0",
"browser": "Edge",
"version": "87.0.664.75",
"platform": "Microsoft Windows",
"source": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 Edg/87.0.664.75"
},
"__v": 0
}
]
what i want to do is, populate the analytics array in links document with the values from analytics document and also sum up the count of true boolean values for each field in os and browser objects. the output structure that i am looking for is -
{
"_id": null,
"visit_count": 20,
"password_protected": false,
"description": null,
"alias": "g",
"short_url": "https://reduced.me/g",
"long_url": "https://google.com",
"created": "2021-01-16T11:49:42.517Z",
"analytics": {
"os": {
"windows": 2,
"linux": 0,
"mac": 0,
"android": 0
},
"browser": {
"opera": 0,
"ie": 0,
"edge": 1,
"safari": 0,
"firefox": 1,
"chrome": 0
}
}
}
here, for example, windows:2 shows the number of times windows had a value of true throughout all the document.
Currently im doing it like this
const analytics = await LinkModel.aggregate([
{ $match: { short_url: req.body.short_url } },
{
$lookup: {
from: 'analytics',
localField: 'analytics',
foreignField: '_id',
as: 'analytics',
},
},
{ $unwind: '$analytics' },
{
$group: {
_id: null,
visit_count: { $first: '$visit_count' },
password_protected: { $first: '$password_protected' },
description: { $first: '$description' },
alias: { $first: '$alias' },
short_url: { $first: '$short_url' },
long_url: { $first: '$long_url' },
created: { $first: '$created' },
windows: {
$sum: { $cond: ['$analytics.os.windows', 1, 0] },
},
linux: {
$sum: { $cond: ['$analytics.os.linux', 1, 0] },
},
mac: {
$sum: { $cond: ['$analytics.os.mac', 1, 0] },
},
android: {
$sum: { $cond: ['$analytics.os.android', 1, 0] },
},
opera: {
$sum: { $cond: ['$analytics.browser.opera', 1, 0] },
},
ie: {
$sum: { $cond: ['$analytics.browser.ie', 1, 0] },
},
edge: {
$sum: { $cond: ['$analytics.browser.edge', 1, 0] },
},
safari: {
$sum: {
$cond: ['$analytics.browser.safari', 1, 0],
},
},
firefox: {
$sum: {
$cond: ['$analytics.browser.firefox', 1, 0],
},
},
chrome: {
$sum: {
$cond: ['$analytics.browser.chrome', 1, 0],
},
},
},
},
])
this does give the output like this
[{
"_id": null,
"visit_count": 20,
"password_protected": false,
"description": null,
"alias": "g",
"short_url": "https://reduced.me/g",
"long_url": "https://google.com",
"created": "2021-01-16T11:49:42.517Z",
"windows": 2,
"linux": 0,
"mac": 0,
"android": 0,
"opera": 0,
"ie": 0,
"edge": 1,
"safari": 0,
"firefox": 1,
"chrome": 0
}]
it has all the data i need but the structure is not right. I am using mongoose as the ORM. Any help would be appreciated. thanks.