Hello friends, I want to use aggregate in Meteor. I did some research and found an old package “sakulstra: aggregate
”. I wrote a function based on this package for general sorting and filtering. My question is, did I do it right, is it right to get your experience and your ideas on how to write better, and also to use aggregate in meteor?
AggregateRequest = function (_collection, _pipeline, _options, wrapperFieldName = 'data') {
const result = {
options: {
pagination: {},
sorting: {}
}
};
result[wrapperFieldName] = [];
let pipeline = _pipeline;
if (_options?.filters) {
const filterQuery = Object.keys(_options.filters).reduce(function (obj, key) {
const _f = [];
_options.filters[key].forEach(f => {
if (f.checked) {
_f.push(f.field);
}
});
obj[key] = {
$in: _f,
};
return obj;
}, {});
pipeline.push({ $match: filterQuery });
}
if (_options?.filtering) {
const $or = []
Object.keys(_options.filtering).reduce(function (obj, key) {
let _obj = {};
_obj[key] = {
$regex: `${_options.filtering[key]}`,
$options: 'i'
};
$or.push(_obj);
}, {});
pipeline.push({ $match: { $or: $or } });
}
pipeline.push({ $count: "count" });
const count = _collection.aggregate(pipeline)[0]?.count;
result.options.pagination.currentPage = 1;
result.options.pagination.pageItems = count || _options?.pagination?.pageItems || 0;
result.options.pagination.totalCount = count || 0;
pipeline.splice(-1, 1); // son eklenen count değeri siliniyor.
if (!count) // count undefined ise zaten sonuç yoktur sorguyu bitiriyorum.
return result;
if (_options?.sorting) {
const sort = {}
sort[_options.sorting.field] = _options.sorting.order;
pipeline.push({ $sort: sort });
result.options.sorting = sort;
}
if (_options?.pagination) {
pipeline.push({ $skip: (_options.pagination.currentPage - 1) * _options.pagination.pageItems });
pipeline.push({ $limit: _options.pagination.pageItems });
result.options.pagination.currentPage = _options.pagination.currentPage;
result.options.pagination.pageItems = _options.pagination.pageItems;
}
result[wrapperFieldName] = _collection.aggregate(pipeline);
return result;
};
I also wrote something like this for a faster way to create a pipeline.
Aggregate = {
addLookup: function (pipeline, from, localField, foreignField, path, preserveNullAndEmptyArrays = false) {
pipeline.push(
{
$lookup: {
from: from,
localField: localField,
foreignField: foreignField,
as: path
},
},
{
$unwind: {
path: `$${path}`,
preserveNullAndEmptyArrays: preserveNullAndEmptyArrays
}
});
},
createProject: function (pipeline, fields) {
const $project = {
_id: 1,
}
fields.forEach(field => {
if (typeof field === 'object') {
const key = Object.keys(field)[0];
const _in = { _id: "$$u._id" };
const obj = {
$let: {
vars: {
u: `$${key}`
},
in: _in,
},
}
field[key].forEach(f => {
_in[f] = `$$u.${f}`
});
$project[key] = obj
} else {
$project[field] = 1;
}
});
pipeline.push({ $project: $project })
},
methods: {
tirKamyon: {
list: function (pipeline) {
Aggregate.addLookup(pipeline, 'users', 'lastEditUserId', '_id', 'lastEditUser');
Aggregate.addLookup(pipeline, 'users', 'createdUserId', '_id', 'createdUser');
Aggregate.addLookup(pipeline, 'tir-kamyon', 'plakaId', '_id', 'tirKamyon');
Aggregate.addLookup(pipeline, 'firma', 'firmaId', '_id', 'firma');
Aggregate.addLookup(pipeline, 'firma', 'malzemeAlinanfirmaId', '_id', 'malzemeAlinanfirma', true);
Aggregate.addLookup(pipeline, 'birim', 'birimId', '_id', 'birim');
Aggregate.addLookup(pipeline, 'dokum-sahasi', 'dokumSahasiId', '_id', 'dokumSahasi');
Aggregate.addLookup(pipeline, 'malzeme-cinsi', 'malzemeCinsiId', '_id', 'malzemeCinsi');
Aggregate.addLookup(pipeline, 'personel', 'personelId', '_id', 'personel');
Aggregate.addLookup(pipeline, 'form-turu', 'formTuruId', '_id', 'formTuru');
Aggregate.addLookup(pipeline, 'santiye', 'santiyeId', '_id', 'santiye');
Aggregate.addLookup(pipeline, 'users', 'onaylayanUserId', '_id', 'onaylayanUser', true);
Aggregate.createProject(pipeline, [
'siraNo',
'onaylimi',
'formTarihi',
'yuklemeYeri',
'seferSayisi',
'alinanMotorin',
'kilometre',
'firmaYetkilisiAdSoyad',
'notlar',
'tonajDataList',
//----
'createdAt',
//----
'tirKamyon',
'firma',
'malzemeAlinanfirma',
'birim',
'dokumSahasi',
'malzemeCinsi',
'personel',
'formTuru',
'santiye',
{ 'lastEditUser': ['emails', 'profile', 'createdAt'] },
{ 'createdUser': ['emails', 'profile', 'createdAt'] },
{ 'onaylayanUser': ['emails', 'profile', 'createdAt'] },
]);
return pipeline;
},
},
isMakinesi: {
list: function (pipeline) {
Aggregate.addLookup(pipeline, 'users', 'lastEditUserId', '_id', 'lastEditUser');
Aggregate.addLookup(pipeline, 'users', 'createdUserId', '_id', 'createdUser');
Aggregate.addLookup(pipeline, 'is-makinesi', 'plakaId', '_id', 'isMakinesi');
Aggregate.addLookup(pipeline, 'birim', 'birimId', '_id', 'birim');
Aggregate.addLookup(pipeline, 'firma', 'firmaId', '_id', 'firma');
Aggregate.addLookup(pipeline, 'personel', 'personelId', '_id', 'personel');
Aggregate.addLookup(pipeline, 'form-turu', 'formTuruId', '_id', 'formTuru');
Aggregate.addLookup(pipeline, 'santiye', 'santiyeId', '_id', 'santiye');
Aggregate.addLookup(pipeline, 'users', 'onaylayanUserId', '_id', 'onaylayanUser', true);
Aggregate.createProject(pipeline, [
'siraNo',
'onaylimi',
'formTarihi',
'yapilinIsTanimi',
'alinanMotorin',
'motorSaati',
'firmaYetkilisiAdSoyad',
'notlar',
'miktar',
//----
'createdAt',
//----
'birim',
'isMakinesi',
'firma',
'personel',
'formTuru',
'santiye',
{ 'lastEditUser': ['emails', 'profile', 'createdAt'] },
{ 'createdUser': ['emails', 'profile', 'createdAt'] },
{ 'onaylayanUser': ['emails', 'profile', 'createdAt'] },
]);
return pipeline;
},
},
makineNakliyesi: {
list: function (pipeline) {
Aggregate.addLookup(pipeline, 'users', 'lastEditUserId', '_id', 'lastEditUser');
Aggregate.addLookup(pipeline, 'users', 'createdUserId', '_id', 'createdUser');
Aggregate.addLookup(pipeline, 'users', 'onaylayanUserId', '_id', 'onaylayanUser', true);
Aggregate.addLookup(pipeline, 'tir-kamyon', 'tasiyanAracId', '_id', 'tasiyanArac');
Aggregate.addLookup(pipeline, 'tir-kamyon', 'tasinanAracTirKamyonId', '_id', 'tasinanAracTirKamyon', true);
Aggregate.addLookup(pipeline, 'is-makinesi', 'tasinanAracIsMakinesiId', '_id', 'tasinanAracIsMakinesi', true);
Aggregate.addLookup(pipeline, 'firma', 'alinanFirmaId', '_id', 'alinanFirma', true);
Aggregate.addLookup(pipeline, 'firma', 'indirilenFirmaId', '_id', 'indirilenFirma', true);
Aggregate.addLookup(pipeline, 'birim', 'birimId', '_id', 'birim');
Aggregate.addLookup(pipeline, 'personel', 'personelId', '_id', 'personel');
Aggregate.addLookup(pipeline, 'form-turu', 'formTuruId', '_id', 'formTuru');
Aggregate.addLookup(pipeline, 'santiye', 'santiyeId', '_id', 'santiye');
Aggregate.createProject(pipeline, [
'siraNo',
'onaylimi',
'formTarihi',
'kilometre',
'firmaYetkilisiAdSoyad',
'notlar',
'miktar',
'aracStatus',
//----
'createdAt',
//----
'birim',
'tasiyanArac',
'tasinanAracTirKamyon',
'tasinanAracIsMakinesi',
'alinanFirma',
'indirilenFirma',
'personel',
'formTuru',
'santiye',
{ 'lastEditUser': ['emails', 'profile', 'createdAt'] },
{ 'createdUser': ['emails', 'profile', 'createdAt'] },
{ 'onaylayanUser': ['emails', 'profile', 'createdAt'] },
]);
return pipeline;
},
},
gidenYakit: {
list: function (pipeline) {
Aggregate.addLookup(pipeline, 'users', 'lastEditUserId', '_id', 'lastEditUser');
Aggregate.addLookup(pipeline, 'users', 'createdUserId', '_id', 'createdUser');
Aggregate.addLookup(pipeline, 'personel', 'yakitiAlanPersonelId', '_id', 'yakitiAlanPersonel');
Aggregate.addLookup(pipeline, 'personel', 'yakitiVerenPersonelId', '_id', 'yakitiVerenPersonel');
Aggregate.addLookup(pipeline, 'firma', 'firmaId', '_id', 'firma', true);
Aggregate.addLookup(pipeline, 'tir-kamyon', 'tirKamyonPlakaId', '_id', 'tirKamyon', true);
Aggregate.addLookup(pipeline, 'is-makinesi', 'isMakinesiPlakaId', '_id', 'isMakinesi', true);
Aggregate.addLookup(pipeline, 'ozel-binek-arac', 'ozelBinekAracPlakaId', '_id', 'ozelBinekArac', true);
Aggregate.addLookup(pipeline, 'santiye', 'santiyeId', '_id', 'santiye', true);
Aggregate.addLookup(pipeline, 'users', 'onaylayanUserId', '_id', 'onaylayanUser', true);
Aggregate.createProject(pipeline, [
'fisNo',
'onaylimi',
'formTarihi',
'verilenYakitLitre',
'kilometre',
'motorSaati',
'notlar',
'aracStatus',
//----
'createdAt',
//----
'firma',
'yakitiAlanPersonel',
'yakitiVerenPersonel',
'tirKamyon',
'isMakinesi',
'ozelBinekArac',
'santiye',
{ 'lastEditUser': ['emails', 'profile', 'createdAt'] },
{ 'createdUser': ['emails', 'profile', 'createdAt'] },
{ 'onaylayanUser': ['emails', 'profile', 'createdAt'] },
]);
return pipeline;
},
},
gelenYakit: {
list: function (pipeline) {
Aggregate.addLookup(pipeline, 'users', 'lastEditUserId', '_id', 'lastEditUser');
Aggregate.addLookup(pipeline, 'users', 'createdUserId', '_id', 'createdUser');
Aggregate.addLookup(pipeline, 'personel', 'yakitiAlanPersonelId', '_id', 'personel');
Aggregate.addLookup(pipeline, 'santiye', 'santiyeId', '_id', 'santiye');
Aggregate.addLookup(pipeline, 'users', 'onaylayanUserId', '_id', 'onaylayanUser', true);
Aggregate.createProject(pipeline, [
'irsaliyeNo',
'onaylimi',
'formTarihi',
'firmaUnvani',
'alinanYakitLitre',
'birimFiyati',
'notlar',
//----
'createdAt',
//----
'personel',
'santiye',
{ 'lastEditUser': ['emails', 'profile', 'createdAt'] },
{ 'createdUser': ['emails', 'profile', 'createdAt'] },
{ 'onaylayanUser': ['emails', 'profile', 'createdAt'] },
]);
return pipeline;
},
},
}
}
I am waiting for your suggestions.