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

ECP-469: Finalize new search schema #368

Merged
merged 12 commits into from
Nov 17, 2020
82 changes: 82 additions & 0 deletions design-documents/graph-ql/coverage/search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Queries

```graphql
type Query {
#Filter supports multiple clauses which will be wrapped in logical AND operator
productSearch(
kokoc marked this conversation as resolved.
Show resolved Hide resolved
phrase: String!,
"Desired size of the search result page"
pageSize: Int = 20,
currentPage: Int = 1,
filter: [SearchClauseInput],
sort: [ProductSearchSortInput]
): ProductSearchResponse!
Copy link
Contributor

Choose a reason for hiding this comment

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

productSearch should be nullable, or all other operations under Query in a request will fail. See #372

}

input ProductSearchSortInput
kokoc marked this conversation as resolved.
Show resolved Hide resolved
{
attribute: String!
direction: SortEnum!
Copy link
Contributor

Choose a reason for hiding this comment

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

why should we have direction as a mandatory attribute?
Most of RDBMS just use a default value of ASC / DESC

Copy link
Member Author

Choose a reason for hiding this comment

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

Here is official elastic search documentation:

The order defaults to desc when sorting on the _score, and defaults to asc when sorting on anything else.

I don't like this uncertainty

ProductSearchSortInput is optional so we can apply some default order, but if developer asks for custom ordering I think it's better to ask for direction as well.

Copy link
Contributor

@DrewML DrewML Apr 21, 2020

Choose a reason for hiding this comment

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

I like @maghamed's idea of having a default. If something isn't critical for an operation to succeed, (I think) it should be optional. Otherwise querying becomes tedious and verbose.

I don't like this uncertainty

I don't see much uncertainty from that quote, if we're only talking about ES.

But, are we planning to only support Elastic Search? If we're ever going to swap search providers, I think it would make sense for the application to define the default so it's consistent.

ProductSearchSortInput is optional so we can apply some default order

I think an application-defined default sort order would be great 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

I think there is no need for any changes. We have the optional ProductSearchSortInput, so we can apply default sort. However, the user needs to specify direction for every custom sort. Does it work?

}

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

input SearchClauseInput {
attribute_code: String!
Copy link

Choose a reason for hiding this comment

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

Inconsistent field name, attribute_code here vs. attribute on other type.

in: [String]
eq: String
range: SearchRangeInput
}

type ProductSearchResponse {
items: [ProductSearchItem]
facets: [Aggregation]
facets_values: [Aggregation]
Copy link

Choose a reason for hiding this comment

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

As discussed with @kokoc verbally, I think facets is sufficient for storing facets aggregation and I am not clear the use case for facet_values.

suggestions: [String]
related_terms: [String]
page_info: SearchResultPageInfo
total_count: Int
}

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

type Highlight {
attribute: String!
value: String!
matched_words: [String]!
Copy link

Choose a reason for hiding this comment

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

It is a common convention to use camelCase for field name (e.g. matchedWords instead of matched_words). Not sure if this is Magento convention or else.

}

interface Bucket {
#Human readable bucket title
title: String!
Copy link

Choose a reason for hiding this comment

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

All fields under the interface (e.g. Bucket) must be listed under any type that implements the interface. e.g. I don't see title listed under StatsBucket, ScalarBucket and RangeBucket.

}

type StatsBucket implements Bucket {
min: Float!
max: Float!
}
kokoc marked this conversation as resolved.
Show resolved Hide resolved

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

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

interface Aggregation {
kokoc marked this conversation as resolved.
Show resolved Hide resolved
Copy link

Choose a reason for hiding this comment

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

Is this supposed to be a type instead of an interface?

Copy link

Choose a reason for hiding this comment

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

I think we should add title field for storing aggregation friendly name. This is so the client (e.g. UI) can use it for display, instead of displaying attribute code.

attribute_code: String!
buckets: [Bucket]!
}
```