menu

Clever Beagle

Chat with other product developers and get help with Clever Beagle's tools and resources.

Channels
Team

Meteor mongo question with Pup

October 4, 2019 at 8:51pm

Meteor mongo question with Pup

October 4, 2019 at 8:51pm (Edited 8 months ago)
I face the following issue which is really painful to solve with a sexy request
I have a JSON collection as below coming from a mongodb request with Meteor
"_id": "wBEFtCcDtPWgGPvZP",
"owner": "sskLSdHFqneZSsSJs",
"referrerEmail": "[email protected]",
"createdAt": "2019-09-29T06:36:46.474Z",
"emailAddresses": [
]
}
{
"_id": "tgWomJepyijvkQmJf",
"owner": "sskLSdHFqneZSsSJs",
"referrerEmail": "[email protected]",
"createdAt": "2019-09-15T17:46:04.054Z",
"emailAddresses": [
]
}
I want as output the list of emailAddresses that are unique and retrieve the latest timestamp associated to each addresses (example below):
{ emailAddress: "[email protected]", latest: "2019-09-15T17:46:04.054Z"}
{ emailAddress: "[email protected]", latest: "2019-09-15T17:46:04.054Z"}
Note: I was inspired by Pup api/Users/actions/queryUsers.js to design my request :
const getInvitations = (options) => {
try {
const query = getQuery(options);
const projection = getProjection(options);
const filterList = invitationCollection.map(({ createdAt, emailAddresses }) => `\n${createdAt} ${emailAddresses}`).join('')
After it's quite ok to parse the output but I'm looking for a mongo query and avoid the code below (far to be sexy):
const nestedlist = [... new Set(invitationCollection.map(invitation => invitation.emailAddresses))]
// flatten the array in array to a signle array
let flatlist = nestedlist.reduce((acc, it) => [...acc, ...it], []);
// remove duplicates
const uniqueValues = [...new Set(flatlist)]; //needs to be returned in json
// I stop coding here, it's not really sexy
. So I was wondering if someone can help to design the proper mongo query instead of heavy parsing.
Any idea ? I'd be very grateful for any help ! I mean it :)
Trapasky

October 5, 2019 at 4:56am
Use aggregates
  • reply
  • like
Use $group, $unwind and $last aggregates
  • reply
  • like
Thank you , but I still face two issues :
  1. Should I aggregate with the code below ?
  2. It's still painful to design design the aggregation request
// aggregation function since package meteorhacks:aggregate looks dead
const aggregate = async function (collection, aggregation) {
var result = await collection.rawCollection().aggregate(aggregation).toArray();
console.log('aggregate result', result);
return result;
};
  1. and then I call for :
const getInvitations = (options) => {
try {
const query = getQuery(options);
const projection = getProjection(options);
// buggy request ...
const aggregateLatestInvitationQuery = {
"$unwind": "$emailAddresses" ,
"$group": {
"_id": { "invitationDate": "$emailAddresses.createdAt" },
"count": { "$sum": 1 }
}
,
"$group": {
"_id": "$_id.invitationDate",
"values": {
"$push": { "invitationDate": "$_id.invitationDate", "count": "$count" }
}
}
};
const invitationCollection = aggregate(Invitations, aggregateLatestInvitationQuery);
return invitationCollection
} catch (exception) {
throw new Error(`[queryInvitations.getInvitations] ${exception.message}`);
}
};
: please come to my help.
Edited
  • reply
  • like