# Class JoinFeatureSet

Object
AbstractResource
AbstractFeatureSet
JoinFeatureSet

All Implemented Interfaces:
  `DataSet, FeatureSet, Resource`

public class JoinFeatureSet extends AbstractFeatureSet
Features containing association to features from two different sources, joined by a SQL-like `JOIN` condition. Each feature in this `FeatureSet` contains two or three properties:

- An optional identifier created from the identifiers of the left and right features.
- Zero or one association to a "left" feature.
- Zero or one association to a "right" feature.

The left and right features appear together in an `JoinFeatureSet` instance when a value from `leftProperty` in the first feature is equal to a value from `rightProperty` in the second feature.

## Implementation note

If iterations in one feature set is cheaper than iterations in the other feature set, then the "costly" or larger `FeatureSet` should be on the left side and the "cheap" `FeatureSet` should be on the right side.

This implementation is read-only.

Since:
  1.0

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static enum`
  `JoinFeatureSet​.Type`
  Specifies whether values on both sides are required (inner join), or only one side (outer join).

  ### Nested classes/interfaces inherited from interface Resource

  `Resource​.FileSet`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `final BinaryComparisonOperator<AbstractFeature>`
  `condition`
  The join condition in the form property from left feature = property from right feature.
  `final FeatureSet`
  `left`
  The first source of features.
  `final FeatureSet`
  `right`
  The second source of features.

  ### Fields inherited from class AbstractResource

  `listeners`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `JoinFeatureSet(Resource parent, FeatureSet left, String leftAlias, FeatureSet right, String rightAlias, JoinFeatureSet​.Type joinType, BinaryComparisonOperator<AbstractFeature> condition, Map<String,?> featureInfo)`
  Creates a new feature set joining the two given sets.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `protected void`
  `clearCache()`
  Clears any cache in this resource, forcing the data to be recomputed when needed again.
  `protected Metadata`
  `createMetadata()`
  Invoked in a synchronized block the first time that `getMetadata()` is invoked.
  `Stream<AbstractFeature>`
  `features(boolean parallel)`
  Returns a stream of all features contained in this dataset.
  `final Optional<Envelope>`
  `getEnvelope()`
  Returns the union of the envelopes in all aggregated feature sets.
  `JoinFeatureSet​.Type`
  `getJoinType()`
  Specifies whether values on both sides are required (inner join), or only one side (outer join).
  `DefaultFeatureType`
  `getType()`
  Returns a description of properties that are common to all features in this dataset.
  `protected void`
  `prepareQueryOptimization(FeatureQuery query, Optimization optimizer)`
  Configures the optimization of a query with information about the expected type of all feature instances.

  ### Methods inherited from class AbstractFeatureSet

  `getFeatureCount, getIdentifier`

  ### Methods inherited from class AbstractResource

  `addListener, getMetadata, getSynchronizationLock, removeListener`

  ### Methods inherited from class Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

  ### Methods inherited from interface Resource

  `addListener, getFileSet, getMetadata, removeListener`

- ## Field Details

  - ### left

    public final FeatureSet left
    The first source of features.

  - ### right

    public final FeatureSet right
    The second source of features.

  - ### condition

    public final BinaryComparisonOperator<AbstractFeature> condition
    The join condition in the form property from left feature = property from right feature. This condition specifies also if the comparison is case sensitive and how to compare multi-values.

- ## Constructor Details

  - ### JoinFeatureSet

    public JoinFeatureSet(Resource parent, FeatureSet left, String leftAlias, FeatureSet right, String rightAlias, JoinFeatureSet.Type joinType, BinaryComparisonOperator<AbstractFeature> condition, Map<String,?> featureInfo) throws DataStoreException
    Creates a new feature set joining the two given sets. The `featureInfo` map defines the name, description or other information for the `FeatureType` created by this method. It can contain all the properties described in `DefaultFeatureType` plus the following ones:
    - `"identifierDelimiter"` — string to insert between left and right identifiers in the identifiers generated by the join operation. If this property is not specified, then no identifier will be generated.
    - `"identifierPrefix"` — string to insert at the beginning of join identifiers (optional).
    - `"identifierSuffix"` — string to insert at the end of join identifiers (optional).
    Parameters:
      `parent` - the parent resource, or `null` if none.
      `left` - the first source of features. This is often (but not necessarily) the largest set.
      `leftAlias` - name of the associations to the `left` features, or `null` for a default name.
      `right` - the second source of features. Should be the set in which iterations are cheapest.
      `rightAlias` - name of the associations to the `right` features, or `null` for a default name.
      `joinType` - whether values on both sides are required (inner join), or only one side (outer join).
      `condition` - join condition as property from left feature = property from right feature.
      `featureInfo` - information about the `FeatureType` of this feature set.
    Throws:
      `DataStoreException` - if an error occurred while creating the feature set.

- ## Method Details

  - ### getJoinType

    public JoinFeatureSet.Type getJoinType()
    Specifies whether values on both sides are required (inner join), or only one side (outer join).
    Returns:
      whether values on both sides are required (inner join), or only one side (outer join).

  - ### getType

    public DefaultFeatureType getType()
    Returns a description of properties that are common to all features in this dataset. This type may contain one identifier and always contains two associations, to the left and `right` set of features respectively.
    Returns:
      a description of properties that are common to all features in this dataset.

  - ### features

    public Stream<AbstractFeature> features(boolean parallel) throws DataStoreException
    Returns a stream of all features contained in this dataset.
    Parameters:
      `parallel` - `true` for a parallel stream (if supported), or `false` for a sequential stream.
    Returns:
      all features contained in this dataset.
    Throws:
      `DataStoreException` - if an error occurred while creating the stream.

  - ### prepareQueryOptimization

    protected void prepareQueryOptimization(FeatureQuery query, Optimization optimizer) throws DataStoreException
    Configures the optimization of a query with information about the expected type of all feature instances. The default implementation uses the knowledge that all features will be instances of exactly the type returned by `getType()`, with no sub-type. Subclasses should override this method if they break this assertion.
    Overrides:
      `prepareQueryOptimization` in class `AbstractFeatureSet`
    Parameters:
      `query` - definition of feature and feature properties filtering applied at reading time.
      `optimizer` - the optimization to configure.
    Throws:
      `DataStoreException` - if an error occurred during the configuration of the optimizer.
    Since:
      1.6

  - ### getEnvelope

    public final Optional<Envelope> getEnvelope() throws DataStoreException
    Returns the union of the envelopes in all aggregated feature sets. This method tries to find a CRS common to all feature sets. If no common CRS can be found, then the envelope is absent.
    Specified by:
      `getEnvelope` in interface `DataSet`
    Overrides:
      `getEnvelope` in class `AbstractResource`
    Returns:
      union of envelopes from all dependencies.
    Throws:
      `DataStoreException` - if an error occurred while computing the envelope.

  - ### createMetadata

    protected Metadata createMetadata() throws DataStoreException
    Invoked in a synchronized block the first time that `getMetadata()` is invoked. The default implementation adds the information documented in the parent class, then adds the dependencies as lineages.
    Overrides:
      `createMetadata` in class `AbstractFeatureSet`
    Returns:
      the newly created metadata, or `null` if unknown.
    Throws:
      `DataStoreException` - if an error occurred while reading metadata from the data stores.

  - ### clearCache

    protected void clearCache()
    Clears any cache in this resource, forcing the data to be recomputed when needed again. This method should be invoked if the data in underlying data store changed.
    Overrides:
      `clearCache` in class `AbstractResource`