Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): Not operator for filtering facet values when using 'search' and MySQL #2685

Open
wants to merge 4 commits into
base: minor
Choose a base branch
from

Conversation

HausTechTeam
Copy link
Contributor

@HausTechTeam HausTechTeam commented Feb 20, 2024

Description

Support for a "not" operator for filtering facet values on the search query when using MySQL. The "not" operator is used together with AND or OR, but not both at the same time - in the same way they currently work.

New GraphQL type:

input FacetValueNotFilterInput {
    and: ID
    or: [ID!]
}

The FacetValueFilterInput type is extended like so:

input FacetValueFilterInput {
    and: ID
    or: [ID!]
    not: FacetValueNotFilterInput 
}

Usage example:

{
  "input": { 
    "facetValueFilters": [
      {
        "not": {
          "or": [1,2,3]
        }      
      }  
    ]
  }
}

Breaking changes

No.

Screenshots

.

Checklist

📌 Always:

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

👍 Most of the time:

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

@HausTechTeam HausTechTeam changed the title Feat/not facet filter operator mysql feat(api): Not operator for filtering facet values when using 'search' and MySQL Feb 20, 2024
@michaelbromley
Copy link
Member

Hi, thanks for bearing with me. I've now had some time to take a look at this PR.

To test the behaviour, I wrote some e2e tests which you can see here: 870dc70

3 of the tests pass, but the testMatchFacetValueFiltersNotAndMultiple test fails.

It uses the following input:

facetValueFilters: [{ not: { and: 'T_1' } }, { not: { and: 'T_2' } }],

I am expecting this to be interpreted as "where the product does not have facet value ID T_1 AND does not have facet value ID T_2".

That is, return all the products (from this csv file) which do not have both the "electronics" (T_1) and "computer" (T_2) facet values.

The result I am getting upon running the tests when in the src/packages/core dir:

$ DB=mariadb yarn e2e default-search-plugin.e2e

 FAIL  e2e/default-search-plugin.e2e-spec.ts > Default search plugin > shop api > matches by FacetValueFilters NOT AND multiple
AssertionError: expected [ 'Road Bike', 'Skipping Rope', …(8) ] to deeply equal [ 'Instant Camera', …(13) ]

- Expected
+ Received

  Array [
-   "Instant Camera",
-   "Camera Lens",
-   "Tripod",
-   "Slr Camera",
    "Road Bike",
    "Skipping Rope",
    "Boxing Gloves",
    "Tent",
    "Cruiser Skateboard",
    "Football",
    "Running Shoe",
    "Spiky Cactus",
    "Orchid",
    "Bonsai Tree",
  ]

 ❯ testMatchFacetValueFiltersNotAndMultiple e2e/default-search-plugin.e2e-spec.ts:360:61
    358|         });
    359|
    360|         expect(result.search.items.map(i => i.productName)).toEqual([
       |                                                             ^
    361|             'Instant Camera',
    362|             'Camera Lens',

i.e., the 4 "photo" products are not being returned, even though they do not have both the "electronics" and "computer" facet values - they have "electronics" and "photo".

Can you take a look at this - is my assumption about the input for this query correct? Did I overlook anything?

@HausTechTeam
Copy link
Contributor Author

Hi! No problem, thank you for providing such a detailed description of the issue. I agree with your interpretation and that the behavior is unexpected.

I've looked into this by running our Vendure fork locally (v2.2.0-next3) and I see some strange results in the generated query. First of all, I don't have the facet value ids "T_1" or "T_2", only numeric values. I'm using yarn populate to populate the dev server, using the provided example data (which I believe is the same as the CSV you linked to).

What happens is that the parameters are set to "-1" if I provide a string value to the facet value id filter, for example:

"facetValueFilters": [    
    { "not": { "and": "T_1" } }, { "not": { "and": "T_2" } }
]

Parameters:

{ __1: -1 }

(just one parameter when it should be two)

But if I provide only numbers instead:

"facetValueFilters": [
    { "not": { "and": "1" } }, { "not": { "and": "2" } }
]

The parameters are set to:

{ _1: 1, _2: 2 }

I'm simply logging the values via getParameters() on the SelectQueryBuilder object.

Unless I've done something wrong with my local setup, perhaps this is the reason? In that case, any other passing tests may be false positives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants