prepareDiscriminatorPipeline.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. 'use strict';
  2. module.exports = function prepareDiscriminatorPipeline(pipeline, schema, prefix) {
  3. const discriminatorMapping = schema && schema.discriminatorMapping;
  4. prefix = prefix || '';
  5. if (discriminatorMapping && !discriminatorMapping.isRoot) {
  6. const originalPipeline = pipeline;
  7. const filterKey = (prefix.length > 0 ? prefix + '.' : prefix) + discriminatorMapping.key;
  8. const discriminatorValue = discriminatorMapping.value;
  9. // If the first pipeline stage is a match and it doesn't specify a `__t`
  10. // key, add the discriminator key to it. This allows for potential
  11. // aggregation query optimizations not to be disturbed by this feature.
  12. if (originalPipeline[0] != null && originalPipeline[0].$match && !originalPipeline[0].$match[filterKey]) {
  13. originalPipeline[0].$match[filterKey] = discriminatorValue;
  14. // `originalPipeline` is a ref, so there's no need for
  15. // aggregate._pipeline = originalPipeline
  16. } else if (originalPipeline[0] != null && originalPipeline[0].$geoNear) {
  17. originalPipeline[0].$geoNear.query =
  18. originalPipeline[0].$geoNear.query || {};
  19. originalPipeline[0].$geoNear.query[filterKey] = discriminatorValue;
  20. } else if (originalPipeline[0] != null && originalPipeline[0].$search) {
  21. if (originalPipeline[1] && originalPipeline[1].$match != null) {
  22. originalPipeline[1].$match[filterKey] = originalPipeline[1].$match[filterKey] || discriminatorValue;
  23. } else {
  24. const match = {};
  25. match[filterKey] = discriminatorValue;
  26. originalPipeline.splice(1, 0, { $match: match });
  27. }
  28. } else {
  29. const match = {};
  30. match[filterKey] = discriminatorValue;
  31. originalPipeline.unshift({ $match: match });
  32. }
  33. }
  34. };