Archived
2

implementation of measurement fields

This commit is contained in:
VLE2FE
2020-06-30 14:16:37 +02:00
parent 52eb828bea
commit 8cf1c14d88
7 changed files with 145 additions and 26 deletions

View File

@ -6,6 +6,7 @@ import NoteFieldValidate from './validate/note_field';
import res400 from './validate/res400';
import SampleModel from '../models/sample'
import MeasurementModel from '../models/measurement';
import MeasurementTemplateModel from '../models/measurement_template';
import MaterialModel from '../models/material';
import NoteModel from '../models/note';
import NoteFieldModel from '../models/note_field';
@ -63,6 +64,9 @@ router.get('/samples', async (req, res, next) => {
if (filters['from-id']) { // from-id specified
const fromSample = await SampleModel.findById(filters['from-id']).lean().exec().catch(err => {next(err);});
if (fromSample instanceof Error) return;
if (!fromSample) {
return res.status(400).json({status: 'Invalid body format', details: 'from-id not found'});
}
if ((filters['to-page'] === 0 && filters.sort[1] === 1) || (filters.sort[1] * filters['to-page'] > 0)) { // asc
query[0].$match.$and.push({$or: [{[filters.sort[0]]: {$gt: fromSample[filters.sort[0]]}}, {$and: [{[filters.sort[0]]: fromSample[filters.sort[0]]}, {_id: {$gte: new mongoose.Types.ObjectId(filters['from-id'])}}]}]});
@ -77,10 +81,6 @@ router.get('/samples', async (req, res, next) => {
query.push({$sort: {[filters.sort[0]]: filters.sort[1], '_id': filters.sort[1]}}); // set _id as secondary sort
}
// if (filters.sort[0].indexOf('material.') >= 0) { // unpopulate materials again
// query.push({$unset: 'material'});
// }
if (filters['to-page']) {
query.push({$skip: Math.abs(filters['to-page'] + Number(filters['to-page'] < 0)) * filters['page-size'] + Number(filters['to-page'] < 0)}) // number to skip, if going back pages, one page has to be skipped less but on sample more
}
@ -88,13 +88,38 @@ router.get('/samples', async (req, res, next) => {
if (filters['page-size']) {
query.push({$limit: filters['page-size']});
}
console.log(filters.fields);
const projection = filters.fields.reduce((s, e) => {s[e] = true; return s; }, {});
let measurementFields = [];
if (filters.fields.find(e => /measurements\./.test(e))) { // joining measurements is required
query.push({$lookup: {from: 'measurements', localField: '_id', foreignField: 'sample_id', as: 'measurements'}});
measurementFields = filters.fields.filter(e => /measurements\./.test(e)).map(e => e.replace('measurements.', ''));
const measurementTemplates = await MeasurementTemplateModel.find({$or: measurementFields.map(e => {return {name: e}})}).lean().exec().catch(err => {next(err);});
if (measurementTemplates instanceof Error) return;
if (measurementTemplates.length < measurementFields.length) {
return res.status(400).json({status: 'Invalid body format', details: 'Measurement key not found'});
}
measurementTemplates.filter(e => e.name !== 'spectrum').forEach(template => { // TODO: hard coded dpt for special treatment, change later
query.push({$set: {[template.name]: {$let: { // add measurements as property [template.name], if one result, array is reduced to direct values
vars: {arr: {$filter: {input: '$measurements', cond: {$eq: ['$$this.measurement_template', mongoose.Types.ObjectId(template._id)]}}}},
in:{$cond: [{$lte: [{$size: '$$arr'}, 1]}, {$arrayElemAt: ['$$arr', 0]}, '$$arr']}
}}}}, {$set: {[template.name]: {$cond: ['$' + template.name + '.values', '$' + template.name + '.values', {}]}}});
});
console.log(measurementFields);
if (measurementFields.find(e => e === 'spectrum')) { // TODO: remove hardcoded as well
query.push(
{$set: {spectrum: {$filter: {input: '$measurements', cond: {$eq: ['$$this.measurement_template', measurementTemplates.filter(e => e.name === 'spectrum')[0]._id]}}}}},
{$set: {spectrum: '$spectrum.values.dpt'}},
{$unwind: '$spectrum'}
);
}
query.push({$unset: 'measurements'});
}
const projection = filters.fields.map(e => e.replace('measurements.', '')).reduce((s, e) => {s[e] = true; return s; }, {});
if (filters.fields.indexOf('added') >= 0) { // add added date
projection.added = {$toDate: '$_id'};
}
if (!(filters.fields.indexOf('_id') >= 0)) { // disable _id explicitly
console.log('disable id');
projection._id = false;
}
query.push({$project: projection});
@ -104,15 +129,16 @@ router.get('/samples', async (req, res, next) => {
if (filters['to-page'] < 0) {
data.reverse();
}
if (filters.csv) { // output as csv // TODO: csv example in OAS
csv(_.compact(data.map(e => SampleValidate.output(e, 'refs'))), ['_id', 'number'], (err, data) => {
console.log(_.compact(data.map(e => SampleValidate.output(e, 'refs', measurementFields))));
if (filters.csv) { // output as csv
csv(_.compact(data.map(e => SampleValidate.output(e, 'refs', measurementFields))), (err, data) => {
if (err) return next(err);
res.set('Content-Type', 'text/csv');
res.send(data);
});
}
else {
res.json(_.compact(data.map(e => SampleValidate.output(e, 'refs')))); // validate all and filter null values from validation errors
res.json(_.compact(data.map(e => SampleValidate.output(e, 'refs', measurementFields)))); // validate all and filter null values from validation errors
}
})
});