lib/stream.js
function(path, value, schema) {
    var bsonType = getBSONType(value);
    // if semantic type detection is enabled, the type is the semantic type
    // or the original bson type if no semantic type was detected. If disabled,
    // it is always the bson type.
    var typeName = (options.semanticTypes) ?
      getSemanticType(value, path) || bsonType : bsonType;
    var type = schema[typeName] = _.get(schema, typeName, {
      name: typeName,
      bsonType: bsonType,
      path: path,
      count: 0
    });
    type.count++;
    // recurse into arrays by calling `addToType` for each element
    if (typeName === 'Array') {
      type.types = _.get(type, 'types', {});
      type.lengths = _.get(type, 'lengths', []);
      type.lengths.push(value.length);
      _.each(value, function(v) {
        addToType(path, v, type.types);
      });

    // recurse into nested documents by calling `addToField` for all sub-fields
    } else if (typeName === 'Document') {
      type.fields = _.get(type, 'fields', {});
      _.forOwn(value, function(v, k) {
        addToField(path + '.' + k, v, type.fields);
      });

    // if the `storeValues` option is enabled, store some example values
    } else if (options.storeValues) {
      type.values = _.get(type, 'values', bsonType === 'String' ?
        new Reservoir(100) : new Reservoir(10000));
      addToValue(type, value);
    }
  }
function(path, value, schema) {
    var bsonType = getBSONType(value);
    // if semantic type detection is enabled, the type is the semantic type
    // or the original bson type if no semantic type was detected. If disabled,
    // it is always the bson type.
    var typeName = (options.semanticTypes) ?
      getSemanticType(value, path) || bsonType : bsonType;
    var type = schema[typeName] = _.get(schema, typeName, {
      name: typeName,
      bsonType: bsonType,
      path: path,
      count: 0
    });
    type.count++;
    // recurse into arrays by calling `addToType` for each element
    if (typeName === 'Array') {
      type.types = _.get(type, 'types', {});
      type.lengths = _.get(type, 'lengths', []);
      type.lengths.push(value.length);
      _.each(value, function(v) {
        addToType(path, v, type.types);
      });

    // recurse into nested documents by calling `addToField` for all sub-fields
    } else if (typeName === 'Document') {
      type.fields = _.get(type, 'fields', {});
      _.forOwn(value, function(v, k) {
        addToField(path + '.' + k, v, type.fields);
      });

    // if the `storeValues` option is enabled, store some example values
    } else if (options.storeValues) {
      type.values = _.get(type, 'values', bsonType === 'String' ?
        new Reservoir(100) : new Reservoir(10000));
      addToValue(type, value);
    }
  }
function ( path , value , schema ) { var bsonType = getBSONType ( value ) ; // if semantic type detection is enabled, the type is the semantic type // or the original bson type if no semantic type was detected. If disabled, // it is always the bson type. var typeName = ( options . semanticTypes ) ? getSemanticType ( value , path ) || bsonType : bsonType ; var type = schema [ typeName ] = _ . get ( schema , typeName , { name : typeName , bsonType : bsonType , path : path , count : 0 } ) ; type . count ++ ; // recurse into arrays by calling `addToType` for each element if ( typeName === 'Array' ) { type . types = _ . get ( type , 'types' , { } ) ; type . lengths = _ . get ( type , 'lengths' , [ ] ) ; type . lengths . push ( value . length ) ; _ . each ( value , function ( v ) { addToType ( path , v , type . types ) ; } ) ; // recurse into nested documents by calling `addToField` for all sub-fields } else if ( typeName === 'Document' ) { type . fields = _ . get ( type , 'fields' , { } ) ; _ . forOwn ( value , function ( v , k ) { addToField ( path + '.' + k , v , type . fields ) ; } ) ; // if the `storeValues` option is enabled, store some example values } else if ( options . storeValues ) { type . values = _ . get ( type , 'values' , bsonType === 'String' ? new Reservoir ( 100 ) : new Reservoir ( 10000 ) ) ; addToValue ( type , value ) ; } }
Takes a field value, determines the correct type, handles recursion into
nested arrays and documents, and passes the value down to `addToValue`.

@param {String}  path     field path in dot notation
@param {Any}     value    value of the field
@param {Object}  schema   the updated schema object
Takes a field value determines the correct type handles recursion into nested arrays and documents and passes the value down to addToValue .