Exclude Attributes

Overview of the ExcludeAttributes Operation

What is ExcludeAttributes?

The ExcludeAttributes operation is a projection operation in CDM that allows users to filter out specified attributes from the source entity or projection. By excluding certain attributes, data models can be streamlined to include only the most relevant or necessary data points, enhancing data clarity and governance.

Key Characteristics:

  • Attribute Filtering: Removes specified attributes from the resolved entity.

  • Selective Application: Allows for precise control over which attributes are excluded.

  • Non-Destructive: If no attributes are specified for exclusion, the operation has no effect, preserving the original attribute structure.

  • Integration with Other Operations: Can be combined with other projection operations to further refine data models.

Purpose in GRIx

Within GRIx, the ExcludeAttributes operation serves to:

  • Enhance Data Governance: By excluding sensitive or irrelevant attributes, organizations can ensure compliance with data protection regulations and internal policies.

  • Streamline Data Models: Reduce complexity by removing unnecessary attributes, making data models easier to manage and understand.

  • Optimize Analytical Processes: Focus analytical efforts on the most pertinent attributes, improving the efficiency and accuracy of risk assessments.

  • Facilitate Data Integration: Align data models with the requirements of external systems by excluding attributes that are not needed or supported.

By incorporating ExcludeAttributes, GRIx data models become more focused, compliant, and efficient, supporting comprehensive risk assessments and decision-making processes.


Functionality and Behavior

How ExcludeAttributes Works

The ExcludeAttributes operation modifies the attribute list of an entity during the resolution process by removing specified attributes. Here's a detailed breakdown of its functionality:

  1. Input Source: The operation accesses the current list of resolved attributes from the source entity or previous operations in the projection pipeline.

  2. Attribute Selection: Users specify a list of attributes to exclude using the excludeAttributes property. These attributes are identified by their names.

  3. Filtering Process:

    • Exclusion: All attributes listed in the excludeAttributes array are removed from the final resolved entity.

    • Retention: Attributes not listed are retained and passed through to the output.

    • Empty Exclusion List: If the excludeAttributes array is empty, no attributes are excluded, and all input attributes are included in the output.

  4. Handling Edge Cases:

    • Non-Existent Attributes: Attempting to exclude attributes that do not exist in the source has no effect and typically results in a warning or informational log.

    • Case Sensitivity: Attribute names are case-sensitive. Ensure accurate casing to successfully exclude the intended attributes.

  5. Final Attribute List: The resolved entity includes all original attributes except those specified for exclusion.

Default Behavior

  • No Exclusion: If no excludeAttributes are specified, the operation does not alter the attribute list.

  • Sequential Processing: When multiple ExcludeAttributes operations are chained, the behavior depends on the runSequentially flag (detailed in examples).

  • Non-Destructive: Only the attributes specified are removed; all other attributes remain intact unless modified by other operations.

API Reference

For detailed technical specifications and additional configuration options, refer to the ExcludeAttributes API Documentation.


Configuration Options

The ExcludeAttributes operation can be customized using several properties to control its behavior during the projection process.

Mandatory Properties

  • $type: Specifies the operation type. For ExcludeAttributes, this should be set to "excludeAttributes".

  • excludeAttributes: An array listing the names of the attributes to be excluded from the source entity or projection.

Optional Properties

  • explanation: Provides a description of what the operation does. Useful for documentation and maintenance purposes.

  • condition: A logical expression that determines whether the operation should execute based on predefined tokens and operators.

  • runSequentially: A boolean flag at the projection level that determines how multiple operations are processed (detailed in examples).

Property Breakdown

Property

Type

Description

Required

$type

string

Specifies the operation type. Must be "excludeAttributes".

Yes

excludeAttributes

array

Lists the names of the attributes to exclude from the source.

Yes

explanation

string

Describes the purpose of the operation for future reference.

No

condition

string

A logical expression that determines whether the operation should execute.

No

Example Configuration

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "address",
        "phoneNumber",
        "email"
    ],
    "explanation": "Excluding address, phoneNumber, and email attributes to streamline the PersonInfo entity."
}

Explanation:

  • $type: Identifies the operation as excludeAttributes.

  • excludeAttributes: Specifies that address, phoneNumber, and email should be excluded from the source entity.

  • explanation: Documents the purpose of excluding these attributes for future reference and maintenance.


Detailed Examples

To provide a clearer understanding of how the ExcludeAttributes operation functions within GRIx, the following examples illustrate its application in various contexts relevant to GRIx’s areas of focus and targets.

Example 1: Using ExcludeAttributes on an Entity Attribute

Scenario: Filtering out specific contact attributes (address, phoneNumber, email) from the Person entity to create a streamlined PersonInfo entity. This operation reduces the data model complexity by excluding less relevant contact information.

GRIx Area of Focus: Data Governance and Compliance

Target: Simplify the data model by removing unnecessary attributes, enhancing data governance by limiting sensitive information exposure.

Base Entity Definition:

  • Person Entity:

    {
        "entityName": "Person",
        "hasAttributes": [
            {
                "name": "name",
                "dataType": "string"
            },
            {
                "name": "age",
                "dataType": "integer"
            },
            {
                "name": "address",
                "dataType": "string"
            },
            {
                "name": "phoneNumber",
                "dataType": "string"
            },
            {
                "name": "email",
                "dataType": "string"
            }
        ]
    }

    Attribute

    Data Type

    Description

    name

    string

    Person's full name.

    age

    integer

    Person's age.

    address

    string

    Person's residential address.

    phoneNumber

    string

    Person's phone number.

    email

    string

    Person's email address.

Projection with ExcludeAttributes:

{
    "name": "PersonInfo",
    "entity": {
        "source": "Person",
        "operations": [
            {
                "$type": "excludeAttributes",
                "excludeAttributes": [
                    "address",
                    "phoneNumber",
                    "email"
                ],
                "explanation": "Excluding address, phoneNumber, and email attributes to streamline the PersonInfo entity."
            }
        ]
    }
}

Explanation:

  • Entity: PersonInfo references the Person entity as its source.

  • ExcludeAttributes Operation:

    • excludeAttributes: Specifies that address, phoneNumber, and email should be excluded.

    • explanation: Documents the reason for excluding these attributes.

Resulting Resolved PersonInfo Entity:

Attribute

Data Type

Description

name

string

Person's full name.

age

integer

Person's age.

Concrete Relation to GRIx: By excluding address, phoneNumber, and email, GRIx ensures that the PersonInfo entity contains only the most essential attributes. This reduction enhances data governance by limiting the exposure of sensitive information and streamlines data processing by focusing on key attributes relevant to risk assessments.


Example 2: Using ExcludeAttributes When Extending an Entity

Scenario: Creating a derived entity, Child, that extends the Person entity and excludes specific inherited attributes (address, email). This operation customizes the inherited attributes to suit the specific needs of the Child entity.

GRIx Area of Focus: Data Reusability and Scalable Data Models

Target: Customize inherited data structures by excluding irrelevant attributes, promoting reusability of base entities while adapting to specific requirements.

Projection with ExcludeAttributes When Extending:

{
    "entityName": "Child",
    "extendsEntity": {
        "source": "Person",
        "operations": [
            {
                "$type": "excludeAttributes",
                "excludeAttributes": [
                    "address",
                    "email"
                ],
                "explanation": "Excluding address and email attributes when extending the Person entity to create the Child entity."
            }
        ]
    },
    "hasAttributes": []
}

Explanation:

  1. Entity: Child extends the Person entity.

  2. ExcludeAttributes Operation:

    • excludeAttributes: Specifies that address and email should be excluded from the inherited attributes.

    • explanation: Documents the purpose of excluding these attributes in the context of the Child entity.

  3. Inheritance: The Child entity inherits all attributes from Person except for address and email.

Resulting Resolved Child Entity:

Attribute

Data Type

Description

name

string

Child's full name.

age

integer

Child's age.

phoneNumber

string

Child's phone number.

Concrete Relation to GRIx: By extending the Person entity and excluding address and email, GRIx enables the creation of specialized entities tailored to specific requirements. This practice promotes data reusability by leveraging existing entity definitions while allowing for customization that aligns with the unique needs of derived entities.


Example 3: Using Multiple ExcludeAttributes Operations

Scenario: Applying multiple ExcludeAttributes operations within the same projection to filter out different sets of attributes based on various criteria. This example demonstrates how the runSequentially flag influences the outcome of multiple exclusions.

GRIx Area of Focus: Advanced Analytical Capabilities and Complex Data Modeling

Target: Demonstrate the behavior of multiple ExcludeAttributes operations within a projection, highlighting the role of the runSequentially flag in determining the final attribute set.

Projection with Multiple ExcludeAttributes Operations:

{
    "name": "PersonInfo",
    "entity": {
        "source": "Person",
        "runSequentially": false,
        "operations": [
            {
                "$type": "excludeAttributes",
                "excludeAttributes": [
                    "address",
                    "email"
                ],
                "explanation": "First exclusion: Removing address and email attributes."
            },
            {
                "$type": "excludeAttributes",
                "excludeAttributes": [
                    "name",
                    "age",
                    "address"
                ],
                "explanation": "Second exclusion: Removing name, age, and address attributes."
            }
        ]
    }
}

Explanation:

  • Entity: PersonInfo references the Person entity as its source.

  • runSequentially: Set to false, meaning that all operations receive the same initial input and operate independently.

  • First ExcludeAttributes Operation:

    • excludeAttributes: Removes address and email.

    • explanation: Documents the first set of exclusions.

  • Second ExcludeAttributes Operation:

    • excludeAttributes: Removes name, age, and address.

    • explanation: Documents the second set of exclusions.

  • Outcome Based on runSequentially:

    • If runSequentially is false: Both operations receive the same initial set of attributes. The final resolved attributes include the union of both exclusions, effectively excluding address, email, name, and age. However, since both operations exclude address, it remains excluded.

    • If runSequentially is true: The first operation excludes address and email. The second operation then operates on the already modified attribute set (without address and email), excluding name and age. The final resolved attributes exclude address, email, name, and age, similar to the non-sequential case, but the process differs in how exclusions are applied.

Resulting Resolved PersonInfo Entity (Based on runSequentially):

  • When runSequentially is false:

    Attribute

    Data Type

    Description

    phoneNumber

    string

    Person's phone number.

  • When runSequentially is true:

    Attribute

    Data Type

    Description

    phoneNumber

    string

    Person's phone number.

Concrete Relation to GRIx: This example illustrates how multiple ExcludeAttributes operations can be applied within a single projection to achieve comprehensive attribute filtering. Understanding the impact of the runSequentially flag allows GRIx users to control the sequence and dependency of operations, ensuring that the final data model aligns with specific analytical and governance requirements.


Best Practices

To maximize the effectiveness of the ExcludeAttributes operation within GRIx, adhere to the following best practices:

1. Precise Attribute Selection

  • Clarity: Ensure that the attributes specified for exclusion are clearly identified and necessary to be removed.

  • Avoid Over-Exclusion: Be cautious not to exclude essential attributes inadvertently, which could compromise data integrity and analytical capabilities.

Example:

Before excluding email, verify that it is not required for subsequent analyses or integrations.

2. Consistent Naming Conventions

  • Documentation: Maintain consistent and descriptive naming conventions for entities and attributes to facilitate easier identification and exclusion.

  • Avoid Ambiguity: Use clear and unambiguous attribute names to prevent confusion during the exclusion process.

Example:

Use primaryEmail and secondaryEmail instead of generic names like email1 and email2 for better clarity.

3. Pair with Complementary Operations

  • Combine with RenameAttributes: Often, ExcludeAttributes is used alongside other operations such as RenameAttributes to further refine the data model.

  • Use with CombineAttributes: After excluding unnecessary attributes, consider using CombineAttributes to merge related remaining attributes for enhanced data structure.

Example:

After excluding address, use CombineAttributes to merge remaining contact details into a unified contactInfo attribute.

4. Leverage the explanation Property

  • Document Intent: Use the explanation property to clearly document the reason behind excluding specific attributes, aiding future maintenance and audits.

  • Maintain Clarity: Ensure that explanations are concise yet comprehensive, providing sufficient context for other team members.

Example:

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "address",
        "phoneNumber",
        "email"
    ],
    "explanation": "Excluding address, phoneNumber, and email attributes to streamline the PersonInfo entity."
}

5. Validate the Final Data Model

  • Consistency Checks: After applying exclusions, validate the resolved entity to ensure that only the intended attributes are excluded.

  • Automated Testing: Implement automated tests to verify the integrity of the data model post-exclusion, especially in complex projection chains.

Example:

Use CDM’s validation methods to confirm that the PersonInfo entity contains only name and age.

codevar resolvedEntity = await corpus.CreateResolvedEntityAsync("PersonInfo", "default", "excludeAttributes");
resolvedEntity.Validate();

6. Understand the Impact of runSequentially

  • Operation Dependency: Recognize how the runSequentially flag affects the outcome of multiple operations, ensuring that exclusions are applied as intended.

  • Plan Operation Order: Strategically order projection operations to achieve the desired attribute filtering and data model structure.

Example:

Set runSequentially to true when subsequent operations depend on the outcomes of previous exclusions.

7. Minimize Redundancy

  • Avoid Duplicate Exclusions: Ensure that the same attribute is not excluded multiple times across different operations unless necessary.

  • Efficient Projection Chains: Streamline projection chains to eliminate redundant operations, enhancing performance and maintainability.

Example:

If address is excluded in the first operation, avoid excluding it again in subsequent operations unless additional processing is required.


Common Use Cases in GRIx

The ExcludeAttributes operation is versatile and can be applied in various scenarios within GRIx to enhance data models. Below are some common use cases:

1. Filtering Out Sensitive Information

Purpose: To comply with data protection regulations by excluding sensitive attributes such as personal identifiers or contact details from certain entities.

Example:

Excluding email and phoneNumber from the UserProfile entity to comply with privacy regulations.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "email",
        "phoneNumber"
    ],
    "explanation": "Excluding email and phoneNumber to comply with GDPR requirements."
}

2. Tailoring Data Models for Specific Analyses

Purpose: To customize data models by excluding irrelevant attributes, making the data more relevant and efficient for targeted analytical operations.

Example:

Excluding address and socialId from the Employee entity when performing a financial risk analysis that does not require location or social media data.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "address",
        "socialId"
    ],
    "explanation": "Excluding address and socialId for focused financial risk analysis."
}

3. Simplifying Data Integration Processes

Purpose: To align internal data models with the requirements of external systems by excluding attributes that are not supported or necessary in the target system.

Example:

Excluding temporaryToken and sessionId from the UserSession entity before exporting data to an external monitoring tool that does not utilize these attributes.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "temporaryToken",
        "sessionId"
    ],
    "explanation": "Excluding temporaryToken and sessionId for compatibility with external monitoring tools."
}

4. Optimizing Data Models for Performance

Purpose: To enhance system performance by excluding non-essential attributes, thereby reducing data volume and complexity.

Example:

Excluding lastLoginTime and passwordHash from the UserAccount entity in a read-heavy reporting system where these attributes are not required.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "lastLoginTime",
        "passwordHash"
    ],
    "explanation": "Excluding lastLoginTime and passwordHash to improve reporting system performance."
}

5. Preparing Data for Machine Learning Models

Purpose: To exclude irrelevant or redundant attributes from datasets used for training machine learning models, ensuring that models are trained on pertinent data.

Example:

Excluding userId, creationDate, and updateDate from the Transaction entity when preparing data for a fraud detection model.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "userId",
        "creationDate",
        "updateDate"
    ],
    "explanation": "Excluding userId, creationDate, and updateDate to focus on transactional features for fraud detection."
}

Impact on GRIx Areas of Focus and Targets

The ExcludeAttributes operation significantly impacts various areas of focus and targets within GRIx by enhancing data model organization, promoting data governance, and supporting comprehensive risk analysis. Below is an analysis of how this operation relates to specific GRIx areas and targets.

1. Risk Assessment and Prioritization

Relation: Excluding irrelevant or redundant attributes enables more focused and accurate risk assessments by concentrating on key data points.

Impact on Targets:

  • Enhanced Clarity: Simplifies the data model, making it easier to identify and assess critical risk factors.

  • Improved Accuracy: Reduces noise in data, leading to more precise risk prioritization and scoring.

2. Mitigation Strategies and Implementation

Relation: By filtering out non-essential attributes related to mitigation measures, ExcludeAttributes ensures that only pertinent data is considered when planning and implementing risk mitigation strategies.

Impact on Targets:

  • Streamlined Planning: Facilitates clearer identification of effective mitigation measures by focusing on relevant attributes.

  • Resource Efficiency: Enhances resource allocation by eliminating distractions from unnecessary data points.

3. Climate Impact Assessment and Environmental Risk

Relation: Excluding extraneous attributes from environmental data models ensures that climate impact assessments are based on the most relevant and actionable data.

Impact on Targets:

  • Focused Analysis: Allows for targeted environmental risk evaluations by concentrating on key climate-related attributes.

  • Data Integrity: Maintains high data integrity by removing unrelated or redundant environmental data.

4. Data Governance and Compliance

Relation: ExcludeAttributes supports data governance by enabling organizations to enforce data minimization principles, ensuring that only necessary data is retained and processed.

Impact on Targets:

  • Regulatory Compliance: Assists in adhering to data protection regulations by excluding sensitive or unnecessary attributes.

  • Enhanced Data Control: Provides greater control over data exposure and access by filtering out specific attributes.

5. Operational Efficiency and Data Reusability

Relation: By reducing the number of attributes in data models, ExcludeAttributes enhances operational efficiency and promotes the reusability of streamlined data structures across different entities and use cases.

Impact on Targets:

  • Efficiency: Lowers data processing overhead by minimizing the number of attributes.

  • Reusability: Encourages the use of optimized data models in various analytical and operational contexts.

6. Advanced Analytical Capabilities

Relation: Excluding irrelevant attributes ensures that advanced analytical models, such as machine learning algorithms, are trained on clean and pertinent data, improving their performance and reliability.

Impact on Targets:

  • Model Performance: Enhances the accuracy and efficiency of analytical models by providing them with relevant data.

  • Data Quality: Improves overall data quality by eliminating unnecessary attributes that could introduce noise into analyses.

7. Scalability and Maintainability

Relation: ExcludeAttributes contributes to scalable and maintainable data models by enabling the removal of attributes that are no longer needed or have become obsolete as the data model evolves.

Impact on Targets:

  • Scalability: Facilitates the growth of data models by ensuring they remain uncluttered and manageable.

  • Maintainability: Simplifies data model maintenance by reducing attribute complexity and preventing attribute bloat.


Troubleshooting

While the ExcludeAttributes operation is straightforward, certain issues may arise during its implementation. Below are common challenges and their solutions:

1. Attribute Name Conflicts

Issue: Attempting to exclude attributes that do not exist in the source entity results in no changes, and the system may log warnings or errors.

Solution:

  • Verify Attribute Names: Ensure that the names listed in excludeAttributes match exactly with the attribute names in the source entity, considering case sensitivity.

  • Review Source Schema: Cross-check the source entity's attribute list to confirm the presence of attributes intended for exclusion.

Example:

If attempting to exclude Email but the attribute is named email, adjust the case to match exactly.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "email"
    ],
    "explanation": "Excluding email attribute for data privacy compliance."
}

2. Incorrect Configuration Syntax

Issue: Misconfiguring the ExcludeAttributes operation, such as incorrect property names, missing required properties, or invalid JSON syntax, leads to operational failures.

Solution:

  • Validate JSON Structure: Ensure that the JSON configuration is well-formed and adheres to the required schema.

  • Refer to API Documentation: Consult the ExcludeAttributes API Documentation to verify correct property usage and syntax.

Example:

Ensure that all mandatory properties ($type, excludeAttributes) are correctly specified.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "address",
        "phoneNumber",
        "email"
    ],
    "explanation": "Excluding address, phoneNumber, and email attributes to streamline the PersonInfo entity."
}

3. Empty Exclusion List

Issue: Providing an empty excludeAttributes array results in no attributes being excluded, effectively making the operation a no-op.

Solution:

  • Review Exclusion Criteria: Confirm whether attribute exclusion is necessary. If not, remove the ExcludeAttributes operation to simplify the projection pipeline.

  • Dynamic Exclusions: If exclusions are conditional, ensure that the excludeAttributes list is populated appropriately based on the condition.

Example:

Only apply exclusions when certain conditions are met.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "address",
        "phoneNumber",
        "email"
    ],
    "condition": "shouldExcludeContactInfo",
    "explanation": "Conditionally excluding contact attributes based on data sensitivity requirements."
}

4. Unintended Attribute Exclusions

Issue: Accidentally excluding attributes that are required for subsequent operations or analyses, leading to incomplete data models.

Solution:

  • Comprehensive Review: Before applying exclusions, review the data model and ensure that no essential attributes are being inadvertently excluded.

  • Use Documentation: Leverage the explanation property to clearly document the purpose of each exclusion, aiding in the identification of potential oversights.

Example:

Ensure that essential attributes like name are not mistakenly included in the excludeAttributes list.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "address",
        "phoneNumber",
        "email"
    ],
    "explanation": "Excluding non-essential contact attributes to focus on core demographic information."
}

5. Confusion with Projection Operation Order

Issue: Misunderstanding the order of projection operations leads to unexpected results, such as excluding attributes before or after other modifications.

Solution:

  • Understand Projection Sequence: Familiarize yourself with how projection operations are applied in sequence, especially when multiple operations are involved.

  • Use runSequentially Appropriately: Determine whether projection operations should be executed sequentially or independently based on their dependencies.

Example:

When combining ExcludeAttributes with other operations like RenameAttributes, ensure that exclusions are applied before or after renaming as intended.

{
    "entityName": "PersonInfo",
    "entity": {
        "source": "Person",
        "runSequentially": true,
        "operations": [
            {
                "$type": "excludeAttributes",
                "excludeAttributes": [
                    "email"
                ],
                "explanation": "Excluding email attribute for privacy reasons."
            },
            {
                "$type": "renameAttributes",
                "renameFormat": "{m}_info",
                "explanation": "Renaming remaining attributes to include '_info' suffix."
            }
        ]
    }
}

6. Impact on Derived Attributes

Issue: Excluding attributes that are used as dependencies for other derived or calculated attributes results in incomplete or faulty derived data.

Solution:

  • Assess Attribute Dependencies: Before excluding an attribute, verify whether it is used in any derived or calculated attributes within the data model.

  • Adjust Derived Logic: Modify or remove dependencies on excluded attributes to maintain data integrity.

Example:

If email is used to derive contactMethod, ensure that either contactMethod is adjusted or email is retained.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "phoneNumber"
    ],
    "explanation": "Excluding phoneNumber as contactMethod will now be derived solely from email."
}

7. Handling Polymorphic Sources

Issue: Excluding attributes from polymorphic sources can lead to inconsistent attribute availability across different derived entities.

Solution:

  • Consistent Exclusions: Apply consistent exclusion rules across all derived entities to maintain uniformity.

  • Conditional Exclusions: Use conditions to tailor exclusions based on the specific type or context of the derived entity.

Example:

Only exclude socialId for certain types within a polymorphic Contact entity.

{
    "$type": "excludeAttributes",
    "excludeAttributes": [
        "socialId"
    ],
    "condition": "contactType != 'SocialMedia'",
    "explanation": "Excluding socialId for non-social media contacts."
}

The ExcludeAttributes operation is a vital feature within GRIx that empowers data architects and risk analysts to refine and streamline data models effectively. By selectively removing unnecessary or sensitive attributes, organizations can enhance data governance, improve analytical focus, and ensure compliance with regulatory standards. This operation not only simplifies data structures but also contributes to the overall efficiency and integrity of risk assessments and management processes.

Adhering to best practices such as precise attribute selection, consistent naming conventions, comprehensive documentation, and understanding the interplay with other projection operations ensures that the use of ExcludeAttributes significantly benefits the GRIx data ecosystem. As GRIx continues to evolve, mastering operations like ExcludeAttributes will be essential for maintaining robust, compliant, and actionable data models in the face of increasingly complex global risk landscapes.


Further Reading and Resources

Last updated

Was this helpful?