The ElasticPress plugin allows connecting to an Elasticsearch server, for example, to show the results of WordPress search sorted by relevance. Besides that, the plugin comes with a few additional features, one of them Autosuggest. That displays results while the user is typing his search into the search field. This post shows you how to use that feature on Apache without having access to the httpd.conf
file.
Requirements
There are the following requirements:
- An Elasticsearch server. I use SearchBox Elasticsearch on Heroku with the Elasticsearch version 6.2.1.
- An Elasticsearch endpoint that is read-only (otherwise, everyone could use the endpoint, because he could find out the endpoint via the dev tools). SearchBox lets you create Access Keys with read-only access.
- The ElasticPress plugin that is connected with you Elasticsearch server.
- An Apache web server, of course.
I tested the described way with the named Elasticsearch 6.2.1 and ElasticPress 2.5.2 on Uberspace 7 (Apache 2.4.6 on CentOS).
The implementation
Trying around
The readme in the deprecated GitHub repo of the autosuggest feature (deprecated because the feature is managed in the ElasticPress repo now) gives an example of how to modify the nginx config to get the functionality working. Uberspace 7 uses nginx, but, of course, I have no access to the config file of the server, so the only way that remains is (as far as I know) the .htaccess
file.
So I tried to modify the rules to work via .htaccess
but without much luck. I asked if it would be theoretically possible via Apache in the ElasticPress repo, and tried around further after getting the info, that this should be possible. I got a hint to Proxypass, but cannot use this without having access to the httpd.conf
file of Apache. After many tries and a 500 server error, maybe caused by disabled proxy submodules, I wrote a mail to Uberspace. The answer: that will not work, because SSL is done via a reverse proxy, not Apache directly (I tested with the https URL of the Elasticsearch server until then). And that was the hint I needed to get it working.
The solution
I do not have experience with nginx but understood, that the Autosuggest readme wants me to redirect an endpoint of my site (for example /es-search
) to the Elasticsearch endpoint. The Heroku solution protects the endpoint with basic auth – the URL of the read-only access key looks like that:
Code language: Bash (bash)http://user:password@example.com
But we cannot write this into the .htaccess
as the rewrite target – the login would not work. I found the solution for that on serverfault.com: the Authorization
header needs to be specified before with the specific login data, and after that, we can set the URL to the Elasticsearch endpoint, without specifying user and password.
The complete solution looks like that:
SetEnvIf Request_URI ^/es-search$/* ADD_ELASTICSEARCH_BASIC_AUTH
RequestHeader set Authorization "Basic XXXXXXXXXXXXXXXXXX" env=ADD_ELASTICSEARCH_BASIC_AUTH
RewriteRule ^es-search$ http://gloin-eu-west-1.searchly.com/indexName/post/_search [P]
Code language: Bash (bash)
We set the Authorization header with the needed credentials for calls against /es-search
and redirect it to the Elasticsearch server in the third line. The XXXXXXXXXXXXXXXXXX
in line 2 needs to be the base64-encoded user:password
string. You can use the following command on Linux, Mac, or the Windows Subsystem for Linux to get the string (I also got this from the serverfault.com answer. Of course, you need to modify user
and pass
to your values):
echo -n 'user:pass' | openssl base64
Code language: Bash (bash)
The http://gloin-eu-west-1.searchly.com/indexName/post/_search
URL needs to be changed to the URL of your endpoint. I needed to use http
here because Uberspace uses a reverse proxy for SSL as written.
Now you need to add the chosen endpoint (here it is /es-search
) to the ElasticPress settings for the Autosuggest feature, enable it and (hopefully) be happy about a working autosuggest for your search field ??
The next step will be trying to modify it, so it not only searches for matches in the title but also in the content.