Skip to content

Conversation

LeftoversTodayAppAdmin
Copy link
Contributor

@LeftoversTodayAppAdmin LeftoversTodayAppAdmin commented May 10, 2025

Description

groupByProduct works well when within a single channel a product has multiple variants and you want to group by the product to have a single row returned.

With multi-vendor stores, multiple vendors can list the same box of cookies with the same barcode as SKU to independently manage their own stock values etc. When querying the default channel we now see multiple products that are the same with the same SKU (barcode). By extending ES to also support groupBySKU, we can now get a unique list of all items across all vendors, grouped by SKU.

Please include a summary of the changes and the related issue.

#3527

Breaking changes

Does this PR include any breaking changes we should be aware of?
No, only adds support for a new type of grouping and is fully backwards compatible. You can however only use one type of grouping at a time, either groupByProduct or groupBySKU, if both are used at the same time a new error is thrown telling the user they can only use one at a time.

Screenshots

You can add screenshots here if applicable.
image

Checklist

📌 Always:

  • [ X ] I have set a clear title
  • [ X ] My PR is small and contains a single feature
  • [ X ] I have checked my own PR

👍 Most of the time:

  • I have added or updated test cases
  • I have updated the README if needed

Summary by CodeRabbit

  • New Features

    • Added the ability to group search results by SKU in addition to grouping by product.
    • Introduced a new input option to enable SKU-based grouping in search queries.
  • Bug Fixes

    • Updated expected search result counts in tests to reflect changes in data and grouping logic.
  • Documentation

    • Clarified when custom product and variant mappings are accessible based on grouping options.
  • Tests

    • Added and updated test cases to cover SKU grouping and adjusted expected results for improved accuracy.

Copy link

vercel bot commented May 10, 2025

@LeftoversTodayAppAdmin is attempting to deploy a commit to the Vendure Team on Vercel.

A member of the Team first needs to authorize it.

@LeftoversTodayAppAdmin LeftoversTodayAppAdmin changed the title fix(elasticsearch-plugin): Fix ElasticSearch groupByProduct to collapse on sku.keyword instead of productId fix(elasticsearch-plugin): Extend ElastSearch to also groupBySKU May 12, 2025
@LeftoversTodayAppAdmin LeftoversTodayAppAdmin changed the title fix(elasticsearch-plugin): Extend ElastSearch to also groupBySKU fix(elasticsearch-plugin): Extend ElasticSearch to also support groupBySKU for multi-vendor store scenarios May 12, 2025
@LeftoversTodayAppAdmin LeftoversTodayAppAdmin changed the title fix(elasticsearch-plugin): Extend ElasticSearch to also support groupBySKU for multi-vendor store scenarios feat(elasticsearch-plugin): Extend ElasticSearch to also support groupBySKU for multi-vendor store scenarios May 12, 2025
Copy link

@michaelbromley michaelbromley moved this to 👀 Under consideration in Vendure OS Roadmap May 20, 2025
@michaelbromley michaelbromley added this to the v3.4.0 milestone May 20, 2025
@LeftoversTodayAppAdmin LeftoversTodayAppAdmin changed the base branch from master to minor May 21, 2025 02:49
@dlhck
Copy link
Collaborator

dlhck commented Jun 20, 2025

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Jun 20, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

coderabbitai bot commented Jun 20, 2025

Walkthrough

This change introduces support for grouping Elasticsearch search results by SKU in addition to the existing product grouping. It updates the GraphQL schema, service logic, type definitions, and tests to handle the new groupBySKU input, ensuring mutual exclusivity with product grouping and adjusting aggregations, mappings, and expected test outcomes accordingly.

Changes

Files/Paths Change Summary
packages/elasticsearch-plugin/e2e/e2e-helpers.ts,
.../elasticsearch-plugin-uuid.e2e-spec.ts,
.../elasticsearch-plugin.e2e-spec.ts
Added and updated tests for groupBySKU search functionality; adjusted expected counts and results.
packages/elasticsearch-plugin/src/api/api-extensions.ts Added groupBySKU Boolean field to the SearchInput GraphQL input type.
packages/elasticsearch-plugin/src/build-elastic-body.ts Modified query builder to support groupBySKU option for Elasticsearch collapse queries.
packages/elasticsearch-plugin/src/elasticsearch.service.ts Updated service logic to support mutually exclusive grouping by SKU or product; adjusted aggregations, mappings, and result handling.
packages/elasticsearch-plugin/src/options.ts Clarified documentation for custom mappings regarding groupBySKU and groupByProduct usage.
packages/elasticsearch-plugin/src/types.ts Added groupBySKU?: boolean to the ElasticSearchInput type.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant GraphQL API
    participant ElasticsearchService
    participant Elasticsearch

    Client->>GraphQL API: Search with SearchInput (groupBySKU or groupByProduct)
    GraphQL API->>ElasticsearchService: search(input)
    ElasticsearchService->>ElasticsearchService: Check groupBySKU and groupByProduct (error if both true)
    ElasticsearchService->>Elasticsearch: Build query with collapse (by SKU or product)
    Elasticsearch-->>ElasticsearchService: Return search results
    ElasticsearchService->>ElasticsearchService: Aggregate and map results (by SKU or product)
    ElasticsearchService-->>GraphQL API: Return grouped results
    GraphQL API-->>Client: Respond with search results
Loading

Possibly related issues

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-06-24T07_14_09_258Z-debug-0.log


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c34257 and 51e4430.

📒 Files selected for processing (2)
  • packages/elasticsearch-plugin/e2e/elasticsearch-plugin-uuid.e2e-spec.ts (2 hunks)
  • packages/elasticsearch-plugin/src/elasticsearch.service.ts (16 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/elasticsearch-plugin/e2e/elasticsearch-plugin-uuid.e2e-spec.ts
  • packages/elasticsearch-plugin/src/elasticsearch.service.ts
⏰ Context from checks skipped due to timeout of 90000ms (19)
  • GitHub Check: e2e tests (20.x, mysql)
  • GitHub Check: e2e tests (22.x, mariadb)
  • GitHub Check: e2e tests (22.x, sqljs)
  • GitHub Check: e2e tests (22.x, postgres)
  • GitHub Check: e2e tests (20.x, mariadb)
  • GitHub Check: e2e tests (20.x, sqljs)
  • GitHub Check: e2e tests (22.x, mysql)
  • GitHub Check: e2e tests (20.x, postgres)
  • GitHub Check: unit tests (20.x)
  • GitHub Check: codegen / codegen
  • GitHub Check: unit tests (22.x)
  • GitHub Check: build (22.x)
  • GitHub Check: build (20.x)
  • GitHub Check: publish_install (ubuntu-latest, 20.x)
  • GitHub Check: publish_install (macos-latest, 20.x)
  • GitHub Check: publish_install (ubuntu-latest, 22.x)
  • GitHub Check: publish_install (macos-latest, 22.x)
  • GitHub Check: publish_install (windows-latest, 22.x)
  • GitHub Check: publish_install (windows-latest, 20.x)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
packages/elasticsearch-plugin/e2e/elasticsearch-plugin-uuid.e2e-spec.ts (2)

69-79: Fix duplicate test description.

The test logic is correct, but the test description is identical to the previous test, making it difficult to distinguish between them.

-    it('no term or filters', async () => {
+    it('no term or filters grouped by SKU', async () => {

94-105: Fix duplicate test description.

The test logic is correct, but the test description is identical to an earlier test.

-        it('with search term', async () => {
+    it('with search term grouped by SKU', async () => {
packages/elasticsearch-plugin/src/elasticsearch.service.ts (2)

195-199: Improve error message for mutual exclusivity.

The validation logic is correct, but the error message could be more helpful to users.

Consider a more descriptive error message:

-            throw new InternalServerError(
-                'groupByProduct and groupBySKU cannot be used at the same time, you can only group by one attribute.',
-            );
+            throw new InternalServerError(
+                'Cannot use both groupByProduct and groupBySKU simultaneously. Please set only one of these options to true.',
+            );

553-553: Consider using a single parameter for grouping mode.

Having two mutually exclusive boolean parameters can be confusing and error-prone.

Consider using an enum or a single parameter to represent the grouping mode:

enum GroupingMode {
    None = 'none',
    Product = 'product',
    SKU = 'sku'
}

private mapProductToSearchResult(hit: SearchHit<VariantIndexItem>, groupingMode: GroupingMode = GroupingMode.None): ElasticSearchResult {
    // Update the logic to use groupingMode
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 210137f and 3c34257.

⛔ Files ignored due to path filters (1)
  • packages/elasticsearch-plugin/e2e/fixtures/e2e-products-full.csv is excluded by !**/*.csv
📒 Files selected for processing (8)
  • packages/elasticsearch-plugin/e2e/e2e-helpers.ts (6 hunks)
  • packages/elasticsearch-plugin/e2e/elasticsearch-plugin-uuid.e2e-spec.ts (2 hunks)
  • packages/elasticsearch-plugin/e2e/elasticsearch-plugin.e2e-spec.ts (11 hunks)
  • packages/elasticsearch-plugin/src/api/api-extensions.ts (1 hunks)
  • packages/elasticsearch-plugin/src/build-elastic-body.ts (2 hunks)
  • packages/elasticsearch-plugin/src/elasticsearch.service.ts (16 hunks)
  • packages/elasticsearch-plugin/src/options.ts (2 hunks)
  • packages/elasticsearch-plugin/src/types.ts (1 hunks)
🔇 Additional comments (15)
packages/elasticsearch-plugin/src/types.ts (1)

21-21: LGTM! Clean type definition extension.

The addition of the optional groupBySKU boolean property follows the established pattern and aligns with the GraphQL schema extension.

packages/elasticsearch-plugin/src/api/api-extensions.ts (1)

41-41: LGTM! Consistent GraphQL schema extension.

The groupBySKU field addition to the SearchInput type properly extends the GraphQL schema and aligns with the corresponding TypeScript type definition.

packages/elasticsearch-plugin/e2e/elasticsearch-plugin-uuid.e2e-spec.ts (1)

57-67: Update expected count is correct.

The test correctly verifies the groupByProduct functionality with the updated expected result count.

packages/elasticsearch-plugin/e2e/e2e-helpers.ts (3)

31-41: LGTM! Updated expected count for product grouping.

The test helper correctly reflects the updated expected result count for product grouping.


43-54: Excellent test coverage for SKU grouping.

The new testGroupBySKU helper function provides focused test coverage by testing with a specific search term "bonsai" to verify SKU grouping behavior.


56-67: Good explicit parameter setting.

Explicitly setting groupBySKU: false in the no-grouping test helps ensure clarity about the expected behavior and prevents any ambiguity.

packages/elasticsearch-plugin/src/build-elastic-body.ts (2)

25-25: LGTM! Consistent parameter extraction.

The groupBySKU parameter is properly extracted from the input alongside other search parameters.


151-153: Verify mutual exclusivity validation exists.

The collapse logic for SKU grouping is correctly implemented. However, both groupByProduct and groupBySKU could potentially be true simultaneously, with the latter overriding the former. The PR objectives mention mutual exclusivity validation - please verify this validation is implemented in the service layer.

#!/bin/bash
# Description: Verify that mutual exclusivity validation exists for groupByProduct and groupBySKU

# Search for validation logic that prevents both grouping options from being used together
rg -A 10 -B 5 "groupByProduct.*groupBySKU|groupBySKU.*groupByProduct" --type ts
packages/elasticsearch-plugin/e2e/elasticsearch-plugin.e2e-spec.ts (3)

53-53: LGTM!

The import of testGroupBySKU helper function is correctly added to support the new SKU grouping test cases.


207-208: Test coverage for SKU grouping looks good.

The new test cases appropriately cover the SKU grouping functionality for both shop and admin APIs, following the existing test pattern.

Also applies to: 485-486


251-252: Verify the test data changes are intentional.

The count increments across multiple test assertions suggest changes to the test data. Please confirm these increases are related to the SKU grouping feature or document what test data was added.

Also applies to: 270-271, 318-319, 333-333, 347-347, 413-413, 426-426, 465-465, 478-478

packages/elasticsearch-plugin/src/options.ts (1)

195-197: Documentation updates are clear and accurate.

The updated comments correctly document the mutual exclusivity of groupByProduct and groupBySKU options and clarify when custom mappings are accessible.

Also applies to: 249-251

packages/elasticsearch-plugin/src/elasticsearch.service.ts (3)

279-284: Cardinality aggregation correctly implemented.

The use of 'sku.keyword' for SKU grouping is correct, as it ensures exact matching on the non-analyzed SKU field.


409-417: SKU aggregation follows consistent pattern.

The implementation correctly mirrors the product grouping logic and uses the appropriate field for SKU cardinality.


636-638: Custom mappings logic correctly handles both grouping modes.

The implementation properly exposes product mappings when grouping by product or SKU, and variant mappings when not grouping, which aligns with the documented behavior.

Also applies to: 647-649

Copy link

vercel bot commented Jun 24, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
docs ✅ Ready (Inspect) Visit Preview Jun 24, 2025 7:14am

Copy link

@github-project-automation github-project-automation bot moved this from 👀 Under consideration to ♻️ In progress in Vendure OS Roadmap Jul 31, 2025
@dlhck dlhck merged commit ec1cc5e into vendure-ecommerce:minor Jul 31, 2025
24 checks passed
@github-project-automation github-project-automation bot moved this from ♻️ In progress to 💯 Ready in Vendure OS Roadmap Jul 31, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Jul 31, 2025
@dlhck dlhck moved this from 💯 Ready to 🚀 Shipped in Vendure OS Roadmap Aug 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants