function attachAspectSubject(sample, subjectModel, aspectModel) {
  // check if sample object contains name
  if (!sample.name || sample.name.indexOf('|') < 0) {
    logger.error('sample object does not contain name', JSON.stringify(sample));
    console.trace('from attachAspectSubject');
    return Promise.resolve(null);
  }

  const nameParts = sample.name.split('|');
  const subAbsPath = nameParts[0];
  const aspName = nameParts[1];
  const subOpts = {
    where: {
      absolutePath: { [Op.iLike]: subAbsPath },
    },
  };
  const aspOpts = {
    where: {
      name: { [Op.iLike]: aspName },
    },
  };

  if (sample.aspect) {
    redisStore.arrayObjsStringsToJson(
      sample.aspect,
      redisStore.constants.fieldsToStringify.aspect
    );
  }

  if (sample.subject) {
    redisStore.arrayObjsStringsToJson(
      sample.subject,
      redisStore.constants.fieldsToStringify.subject
    );
  }

  return Promise.all([
    sample.aspect ? sample.aspect : aspectModel.findOne(aspOpts),
    sample.subject ? sample.subject : subjectModel.findOne(subOpts),
  ])
  .then((response) => {
    let asp = response[ASPECT_INDEX];
    let sub = response[SUBJECT_INDEX];

    if (!sub) {
      const message = `Subject not found by Sample abs path ${subAbsPath}`;
      throw new Error(message);
    }

    if (!asp) {
      const message = `Aspect ${aspName} not found`;
      throw new Error(message);
    }

    sub = sub.get ? sub.get() : sub;
    asp = asp.get ? asp.get() : asp;

    delete asp.writers;
    delete sub.writers;

    sample.aspect = asp;
    sample.subject = sub;

    /*
     * attach absolutePath field to the sample. This is done to simplify the
     * filtering done on the subject absolutePath
     */
    sample.absolutePath = subAbsPath;
    return sample;
  });
} // attachAspectSubject
/**
 * When passed in a sample, its related subject and aspect is attached to the
 * sample. If useSampleStore is set to true, the subject ans aspect is fetched
 * for the cache instead of the database.
 * @param {Object} sample - The sample instance.
 * @param {Model} subjectModel - The database subject model.
 * @param {Model} aspectModel - The database aspect model.
 * @returns {Promise} - which resolves to a complete sample with its subject and
 *   aspect.
 */
When passed in a sample, its related subject and aspect is attached to the
sample. If useSampleStore is set to true, the subject ans aspect is fetched
for the cache instead of the database.
@param {Object} sample - The sample instance.
@param {Model} subjectModel - The database subject model.
@param {Model} aspectModel - The database aspect model.
@returns {Promise} - which resolves to a complete sample with its subject and
aspect.
When passed in a sample its related subject and aspect is attached to the sample . If useSampleStore is set to true the subject ans aspect is fetched for the cache instead of the database . @param { Object } sample - The sample instance . @param { Model } subjectModel - The database subject model . @param { Model } aspectModel - The database aspect model . @returns { Promise } - which resolves to a complete sample with its subject and aspect .
function attachAspectSubject(sample, subjectModel, aspectModel) {
  if (!sample.name || sample.name.indexOf('|') < 0) {
    logger.error('sample object does not contain name', JSON.stringify(sample));
    console.trace('from attachAspectSubject');
    return Promise.resolve(null);
  }
  const nameParts = sample.name.split('|');
  const subAbsPath = nameParts[0];
  const aspName = nameParts[1];
  const subOpts = {
    where: {
      absolutePath: { [Op.iLike]: subAbsPath },
    },
  };
  const aspOpts = {
    where: {
      name: { [Op.iLike]: aspName },
    },
  };
  if (sample.aspect) {
    redisStore.arrayObjsStringsToJson(
      sample.aspect,
      redisStore.constants.fieldsToStringify.aspect
    );
  }
  if (sample.subject) {
    redisStore.arrayObjsStringsToJson(
      sample.subject,
      redisStore.constants.fieldsToStringify.subject
    );
  }
  return Promise.all([
    sample.aspect ? sample.aspect : aspectModel.findOne(aspOpts),
    sample.subject ? sample.subject : subjectModel.findOne(subOpts),
  ])
  .then((response) => {
    let asp = response[ASPECT_INDEX];
    let sub = response[SUBJECT_INDEX];
    if (!sub) {
      const message = `Subject not found by Sample abs path ${subAbsPath}`;
      throw new Error(message);
    }
    if (!asp) {
      const message = `Aspect ${aspName} not found`;
      throw new Error(message);
    }
    sub = sub.get ? sub.get() : sub;
    asp = asp.get ? asp.get() : asp;
    delete asp.writers;
    delete sub.writers;
    sample.aspect = asp;
    sample.subject = sub;
    sample.absolutePath = subAbsPath;
    return sample;
  });
} 
function attachAspectSubject ( sample , subjectModel , aspectModel ) { if ( ! sample . name || sample . name . indexOf ( '|' ) < 0 ) { logger . error ( 'sample object does not contain name' , JSON . stringify ( sample ) ) ; console . trace ( 'from attachAspectSubject' ) ; return Promise . resolve ( null ) ; } const nameParts = sample . name . split ( '|' ) ; const subAbsPath = nameParts [ 0 ] ; const aspName = nameParts [ 1 ] ; const subOpts = { where : { absolutePath : { [ Op . iLike ] : subAbsPath } , } , } ; const aspOpts = { where : { name : { [ Op . iLike ] : aspName } , } , } ; if ( sample . aspect ) { redisStore . arrayObjsStringsToJson ( sample . aspect , redisStore . constants . fieldsToStringify . aspect ) ; } if ( sample . subject ) { redisStore . arrayObjsStringsToJson ( sample . subject , redisStore . constants . fieldsToStringify . subject ) ; } return Promise . all ( [ sample . aspect ? sample . aspect : aspectModel . findOne ( aspOpts ) , sample . subject ? sample . subject : subjectModel . findOne ( subOpts ) , ] ) . then ( ( response ) => { let asp = response [ ASPECT_INDEX ] ; let sub = response [ SUBJECT_INDEX ] ; if ( ! sub ) { const message = ` ${ subAbsPath } ` ; throw new Error ( message ) ; } if ( ! asp ) { const message = ` ${ aspName } ` ; throw new Error ( message ) ; } sub = sub . get ? sub . get ( ) : sub ; asp = asp . get ? asp . get ( ) : asp ; delete asp . writers ; delete sub . writers ; sample . aspect = asp ; sample . subject = sub ; sample . absolutePath = subAbsPath ; return sample ; } ) ; }
When passed in a sample, its related subject and aspect is attached to the
 sample.
When passed in a sample its related subject and aspect is attached to the sample .
// check if sample object contains name /*
     * attach absolutePath field to the sample. This is done to simplify the
     * filtering done on the subject absolutePath
     */ // attachAspectSubject