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

[EAP] Search Service in Storefront App #374

Open
mslabko opened this issue Oct 8, 2020 · 5 comments
Open

[EAP] Search Service in Storefront App #374

mslabko opened this issue Oct 8, 2020 · 5 comments

Comments

@mslabko
Copy link
Member

mslabko commented Oct 8, 2020

As a Headless Magento Commerce Customer, 

I would like to search the entire catalog for products or limit the search on selected filters

So that

I can get to the products  I want in a fast and efficient manner. 

Acceptance Criteria

  • The existing graphql schema is preserved and all filters and aggregations are supported. 

  • The new Search graphql schema is also supported by the search service.

  • Graphql supports full-text search and the search response supports pagination and sorting.

    • The default page size must be 20.
  • Search results must return aggregations if requested by the user. 

  • Search results can be refined further by specifying one or more filers. 

    • All attributes that enabled to search and filtering in the admin must automatically be available for filtering in the graphql schema. 
    • A filter must support OR operation if multiple values are specified for it. for ex color: {in:["Red", "Blue"]}.
  • Static tests which verify that we don’t have prohibited dependencies from storefront to monolith and vice versa.

  • Storefront services should be compatible with SaaS, which means that they might be easily substituted with SaaS services later, or they might communicate with SaaS services instead of Magento SF services.

  • That compatibility assumably should be implemented based on the Storefront API level, so that Storefront API should be compatible with RPC.

 

Implementation details

For the 1st Phase as a "transition" solution was decided to go with the following approach:

  •  Create a new Search Service with SF API
    • Create SF API (ptotobuf schema) to handle only Query (GET) API 
    • gRPC Query API serves new GQL [search schema|https://git.corp.adobe.com/magento-datalake/search-service/blob/master/src/main/resources/com.adobe.magento.search/productsearch.graphqls] (see comment for details) along with existing GQL search Shema
  • The existing full-text search index (elasticsearch index) from Magento Monolith is directly used by Search Service
    • Existing code from Magento Monolith required to serve Search Query is copy-pasted and adapted for Search Service
    • Any code related to indexation process or any "manage" logic should be skipped and not copy-pasted to Search Service
    • Possibly to do a direct call to table in DB (e.g. to obtain a list of stop-words)
  • Search Service should have a configuration (stored in env.php) with specifying credentials to ES index for fulltext search (refer to Monolith)
  • for first iteration Search Response should contain only product "IDs" and "facets" to build aggregation

Search Service may be a simple wrapper on \Magento\Framework\Api\Search\SearchInterface::search to simplify implementation

 

 

 

@m2-assistant
Copy link

m2-assistant bot commented Oct 8, 2020

Hi @mslabko. Thank you for your report.
To help us process this issue please make sure that you provided sufficient information.

Please, add a comment to assign the issue: @magento I am working on this


@mslabko
Copy link
Member Author

mslabko commented Oct 8, 2020

New GQL schema which should be supported

type Price {
    amount: Float,
    currency: String
}

type ProductItem {
    id: ID
    sku: String
    url: String
    imageUrl: String
    price: Price
    name: String
}

# If from or to fields are omitted, $gte or $lte filter will be applied
input SearchRangeInput {
    from: Float
    to: Float
}

input SearchClauseInput {
    attribute: String!
    # an array of values to filter on
    in: [String]
    # a string to filter on
    eq: String
    # range to filter on
    range: SearchRangeInput
}

# This enumeration indicates whether to return results in ascending or descending order
enum SortEnum {
    ASC
    DESC
}

input ProductSearchSortInput {
    attribute: String!
    direction: SortEnum!
}

type SearchResultPageInfo {
    # Specifies which page of results to return
    currentPage: Int
    # Specifies the maximum number of items to return
    pageSize: Int
    # Total pages
    totalPages: Int
}

interface Bucket {
    #Human readable bucket title
    title: String!
}

type StatsBucket implements Bucket {
    title: String!
    min: Float!
    max: Float!
}

type ScalarBucket implements Bucket {
    title: String!
    #Could be used for filtering and may contain non-human readable data
    id: ID!
    count: Int!
}

type RangeBucket implements Bucket {
    title: String!
    from: Float!
    to: Float!
    count: Int!
}

type Aggregation {
    title: String!
    attribute: String!
    buckets: [Bucket]!
}

type Highlight {
    attribute: String!
    value: String!
    matchedWords: [String]!
}

type ProductSearchItem {
    product: ProductItem!
    highlights: [Highlight]
}

type ProductSearchResponse {
    totalCount: Int
    items: [ProductSearchItem]
    facets: [Aggregation]
    suggestions: [String]  # Should be ignored, available only for "Live Search"
    relatedTerms: [String] # Should be ignored, available only for "Live Search"
    pageInfo: SearchResultPageInfo
}

type Query {
    productSearch(phrase: String!,
                    pageSize: Int = 20,
                    currentPage: Int = 1,
                    filter: [SearchClauseInput!],
                    # One or more sortings are applied to the same results.
                    sort: [ProductSearchSortInput!]): ProductSearchResponse!

    notImplemented(searchRangeInput: SearchRangeInput):Bucket
    scalarBucket: ScalarBucket
    statsBucket: StatsBucket
    rangeBucket: RangeBucket
}

# Only a single graphql file (in the project) should have schema definition.
# other graphql files must not have schema definition.
schema {
    query: Query
}


@nrkapoor nrkapoor added this to the EAP milestone Oct 12, 2020
@mslabko mslabko assigned lykhachov and owlsmage and unassigned lykhachov Oct 19, 2020
@lykhachov
Copy link
Contributor

@magento I am working on this

@m2-assistant
Copy link

m2-assistant bot commented Oct 19, 2020

Hi @lykhachov! 👋
Thank you for collaboration. Only members of Community Contributors Team are allowed to be assigned to the issue. Please use @magento add to contributors team command to join Contributors team.

@lykhachov
Copy link
Contributor

magento/magento2#30778

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment