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

ElasticSearch: Allow custom search queries #364

Closed
Tyratox opened this issue Jun 6, 2020 · 5 comments
Closed

ElasticSearch: Allow custom search queries #364

Tyratox opened this issue Jun 6, 2020 · 5 comments

Comments

@Tyratox
Copy link
Contributor

Tyratox commented Jun 6, 2020

Is your feature request related to a problem? Please describe.
I'm quite happy with the current implementation of the search plugins but the search options for both, the elastic search and the default search are a little limited. For the default search I guess that is fine but for the elastic search plugin it would be nice to have more options. For example wildcard queries and fuzzy searches aren't supported.
In my specific case I would like to run wildcard queries on productName and productVariantName and the existing multi_match query on the remaining fields such as the description, i.e. something like

{
    "query": {
        "bool": {
            "should": [
                {
                    "query_string": {
                        "query": "*term*",
                        "fields": ["productName", "productVariantName"]
                    }
                },
                {
                    "multi_match": {
                        "query": "term",
                        "type": "best_fields",
                        "fields": ["sku", "description"]
                    }
                }
            ]
        }
    }
}

Describe the solution you'd like
The easiest and most powerful option would probably be to allow a custom function, let's say

adjustQuery(query: any, input: ElasticSearchInput, searchConfig: DeepRequired<SearchConfig>, channelId: ID, enabledOnly: boolean): any

that is called at the end of

export function buildElasticBody(
input: ElasticSearchInput,
searchConfig: DeepRequired<SearchConfig>,
channelId: ID,
enabledOnly: boolean = false,
): SearchRequestBody {

, i.e. in line 91

return {
query,
sort: sortArray,
from: skip || 0,
size: take || 10,
};

return {
  adjustQuery(query, input, searchConfig, channelId, enabledOnly),
  sort: sortArray,
  from: skip || 0,
  size: take || 10,
};

Describe alternatives you've considered
An alternative would be to create a very complex option object that could be passed to the plugin. This would require a lot of work compared to the solution described above.

Additional context

@Tyratox Tyratox changed the title ElasticSearch: Allow custom elastic search queries ElasticSearch: Allow custom search queries Jun 6, 2020
@michaelbromley
Copy link
Member

Just so I fully understand the context: can you explain the benefit of this approach over just providing e.g. a rawQuery(query: JSON): JSON query to allow arbitrary Elasticsearch queries to be performed on the index?

@Tyratox
Copy link
Contributor Author

Tyratox commented Jun 8, 2020

I mean that'd be perfectly fine as well. I'm just not sure where this rawQuery would have to be called as it would always depend on the input passed to the search query and thus I thought the easiest option would be to allow modifications in the callback provided by the plugin. But I didn't look at the whole plugin / search plugin api so it's possible I'm completely missing something.

@michaelbromley
Copy link
Member

To be clear, I like your solution - just exploring your reasoning a bit. I can imagine a use for both to be honest. Your solution has the benefit of integrating with the existing API, with all the benefits of having the existing pagination/sorting/filtering already in place. So e.g. it would just work in the Admin UI.

Perhaps exposing a raw query would have some security implications (e.g. can you DOS an ES instance with a really expensive query?) and we should leave it to individual implementers to add it themselves if they see fit. After all if you already have an ES instance available, adding a rawQuery pass-through query is a pretty trivial Vendure plugin.

Would you like to implement and PR your solution?

@Tyratox
Copy link
Contributor Author

Tyratox commented Jun 8, 2020

Oh I see, now I understand what you meant. Yes my thoughts were that the existing elastic search plugin already has a lot of features implemented (e.g. customProductMappings, integration with the admin / standard search api etc.) and thus I thought I'd be easier to add such a option than to implement the whole plugin on your own if you wanted a slightly different query on the same index.

And yes, exposing a rawQuery in the graphql shop api wouldn't be a great idea as some queries can be pretty expensive. (The example I provided already is much more expensive than the standard implementation of the plugin but I wasn't entirely happy with the search results when used in a typeahead search field as no in word matching is done.)

I thought what you meant is a typescript function that could be called from other plugins that implement a custom search for example. But as you already mentioned writing a plugin that does a simple REST request isn't all too difficult.

Yes, if you think this solution is okay then I'd be happy to create a PR.

@michaelbromley
Copy link
Member

Great, then send in a PR when you can :)

Tyratox added a commit to Tyratox/vendure that referenced this issue Jun 8, 2020
The discussion for the feature took place in vendure-ecommerce#364. This commit closes vendure-ecommerce#364.
Tyratox added a commit to Tyratox/vendure that referenced this issue Jun 8, 2020
The discussion for the feature took place in vendure-ecommerce#364. This commit closes vendure-ecommerce#364.

squash
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

No branches or pull requests

2 participants