Problem/Motivation
Elastic provides the ability for business users to build rule sets in Kibana. These rule sets can be added to the processing of a query using the retriever api.
GET movies/_search
{
"retriever": {
"rule": {
"match_criteria": {
"query_string": "harry potter"
},
"ruleset_ids": [
"my-ruleset"
],
"retriever": {
"standard": {
"query": {
"query_string": {
"query": "harry potter"
}
}
}
}
}
}
}
The standard query is wrapped in a standard retriever, which is again wrapped in a rule retriever.
The implementation challenges for us at this level are that the keys for the key/value pairs in the rule section are user defined, and that data must be duplicated from the inputs in the standard query into the value for these arbitrary keys.
The mapping of views filter values and any static values to user-defined keys can be captured in a configuration entity.
Proposed resolution
- Create a configuration entity that collects:
- The elastic rule set ID.
- View ID and display ID.
- Key value pairs for for any search template parameters with static values.
- Key value pairs for user input in which keys are the template parameter key and values are a filter identifier to use as a data source.
- Use
hook_views_query_alterto add the search template entity id to the query as an option - Detect the presence of the option in our query process and divert the request to a template api request.
Remaining tasks
User interface changes
API changes
Data model changes
Issue fork elasticsearch_connector-3574791
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3574791-rule-retriever
changes, plain diff MR !188
- 3574791-search-templates
changes, plain diff MR !176
Comments
Comment #2
fathershawnComment #3
fathershawnComment #4
fathershawnInitial work will be on this MVP version. Eventually I'd like to incorporate the ability to create and maintain the template itself via Drupal.
Comment #6
fathershawnComment #7
fathershawnTests passing - phstan is not picking up the class alias for Yaml class change in D11 but that's the only issue.
Comment #8
fathershawnWell I need to add a functional test for the form properly saving and reloading.
I tried to "improve" my code to use#config_targetwhich some sources stated to work with config entities, and tried to revert back and missed something. My key-value pairs are not saving.Comment #9
fathershawnFalse alarm: needed a cache rebuild - Still should probably add a form test :)
Comment #11
fathershawnAre we supporting D11 only? Asking because in D10 the
decodemethod is only in `\Drupal\Core\Serialization\Yaml` but it's moved into the other class in D11.Comment #12
mparker17Huh, didn't know that! (aside: then why didn't my change fix
phpstanand breakphpstan (previous major)??)AFAIK we want to support both Drupal 10 and Drupal 11.
I guess we need to use
\Drupal\Component\Utility\DeprecationHelper::backwardsCompatibleCall()to call the correct class based on which version of Core we're working with.More information in Changelog 3379306: DeprecationHelper helps modules support multiple versions of core
Comment #13
fathershawnI was wrong! The `decode` method in the Core class became an override of the Component class in 10.3 and is removed in 11. Your change was correct!
Comment #14
fathershawnAll tests and quality checks passing
Comment #15
fathershawnI'm rebasing and will update tomorrow
Comment #16
fathershawnFixed some minor errors found testing in my site
Comment #17
fathershawnLooks like we need more nuanced handling of the default
_searchbody produced byQueryParamBuilder::buildQueryParamsto get things where they need to go in a search template.Comment #18
fathershawnI amended the template param builder to put the
querykey from the standard body params into adrupal_queryparameter, and placing an emptymatch_allquery when there is no top level query. This happens if the fulltext box is empty for instance.I am putting everything else in a
drupal_search_otherparameter as at least when usingretrieversthose values need to be first in the template.Comment #20
fathershawnComment #22
fathershawnAll tests passing
Comment #23
fathershawnAll tests passing and queries behaving as expected in elastic! I'd like to find the best way to integrate these mappings in the views UI and put the retriever config as third-party settings on the view.
Suggestions please!
Comment #24
fathershawnFixed un-selected view data
Comment #25
fathershawnFixed bad data after second form save
Comment #26
fathershawnWe need "rank_window_size" >= "from" + "size" since the "rank_window_size" is constraining the # of docs to return.
Comment #27
fathershawnAdjusted the test to check 'rank_window_size'.
Comment #28
fathershawnAdded a condition for facets
Comment #29
mparker17I'm in the early stages of reviewing this, so I may have additional feedback, but off the top of my head, I've noticed two potential issues.
First, I noticed that when I switched to the branch, the status report showed...
... running
drush -y updatedbdid not fix it.AFAIK this means that the merge request will need an update hook that calls...
(you could also do this in a a post-update hook)
The other thing I noticed is that there are several references to either
elastic_rule_retrieverorelastic-rule-retriever.Regrettably, I would prefer these to be named
elasticsearch_connector_retriever/elasticsearch-connector-retriever, in order to keep them properly namespaced (unless there is some technical limitation why they can't be named that (e.g.: because of some internal length limit - but if that's the case, please mention that in the code!)).I apologize for the verbosity. 🫤
Comment #30
fathershawnThe entity type issue may be another good reason to put this in a submodule? Maybe the first retriever in an
elasticsearch_connector_retrieversmodule since there are other retrievers that elastic supports and that would give an expansion point?Comment #31
mparker17As discussed in Slack with @fathershawn, the code in this issue relies on a feature that's only available with an Elastic Cloud subscription. This means we cannot test it properly in the main module because we can only spin up an elasticsearch open-source copy in Drupal's CI environment.
Mainly because we cannot test it, @fathershawn and I agreed that this feature would be better in a narrowly-focused submodule. #3554964: Add an event to modify query parameters created by QueryParamBuilder makes that submodule possible.
But now that #3554964: Add an event to modify query parameters created by QueryParamBuilder is in, I'm going to move this back to "Needs work".
Thanks!