• Stars
    star
    125
  • Rank 285,495 (Top 6 %)
  • Language
    PHP
  • Created over 10 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A drop-in replacement for WP_Query to leverage Elasticsearch for complex queries

Elasticsearch Wrapper for WP_Query

A drop-in replacement for WP_Query to leverage Elasticsearch for complex queries.

Warning!

This plugin is currently in beta development, and as such, no part of it is guaranteed. It works (the unit tests prove that), but we won't be concerned about backwards compatibility until the first release. If you choose to use this, please pay close attention to the commit log to make sure we don't break anything you've implemented.

Instructions for use

This is actually more of a library than it is a plugin. With that, it is plugin-agnostic with regards to how you're connecting to Elasticsearch. It therefore generates Elasticsearch DSL, but does not actually connect to an Elasticsearch server to execute these queries. It also does no indexing of data, it doesn't add a mapping, etc. If you need an Elasticsearch WordPress plugin, we also offer a free and open-source option called SearchPress.

Once you have your Elasticsearch plugin setup and you have your data indexed, you need to tell this library how to use it. If the implementation you're using has an included adapter, you can load it like so:

es_wp_query_load_adapter( 'adapter-name' );

If your Elasticsearch implementation doesn't have an included adapter, you need to create a class called ES_WP_Query which extends ES_WP_Query_Wrapper. That class should, at the least, have a method query_es() which executes the query on the Elasticsearch server. Here's an example:

class ES_WP_Query extends ES_WP_Query_Wrapper {
	protected function query_es( $es_args ) {
		return wp_remote_post( 'http://localhost:9200/wordpress/post/_search', array( 'body' => json_encode( $es_args ) ) );
	}
}

See the included adapters for examples and inspiration.

Once you have an adapter setup, there are two ways you can use this library.

The first, and preferred, way to use this library is to instantiate ES_WP_Query instead of WP_Query. For instance:

$q = new ES_WP_Query( array( 'post_type' => 'event', 'posts_per_page' => 20 ) );

This will guarantee that your query will be run using Elasticsearch (assuming that the request can and should use Elasticsearch) and you should have no conflicts with themes or plugins. The resulting object ($q in this example) works just like WP_Query outside of how it gets the posts.

The second way to use this library is to add 'es' => true to your WP_Query arguments. Here's an example:

$q = new WP_Query( array( 'post_type' => 'event', 'posts_per_page' => 20, 'es' => true ) );

In one regard, this is a safer way to use this library, because it will fall back on good 'ole WP_Query if the library ever goes missing. However, because it depends on the normal processing of WP_Query, it's possible for a plugin or theme to create conflicts, where that plugin or theme is trying to modify WP_Query through one of its provided filters (see below for additional details). In that regard, this can be a very unsafe way to use this library.

Regardless of which way you use the library, everything else about the object should work as per usual.

Differences with WP_Query and Unsupported Features

Meta Queries

  • Regexp comparisons are not supported. The regular expression syntax is slightly different in Elasticsearch vs. PHP, so even if we tried to support them, it would result in a lot of unexpected behaviors. Furthermore, regular expressions are very resource-intensive in Elasticsearch, so you're probably better off just using WP_Query for these queries regardless.
    • If you try to use a regexp query, ES_WP_Query will throw a _doing_it_wrong() notice.
  • LIKE comparisons are incongruous with MySQL. In ES_WP_Query, LIKE-comparison meta queries will run a match query against the analyzed meta values. This will behave similar to a keyword search and will generally be more useful than a LIKE query in MySQL. However, there are notably differences with the MySQL implementation and ES_WP_Query will very likely produce different search results, so don't expect it to be a drop-in replacement.

A note about WP_Query filters

Since this library removes MySQL from most of the equation, the typical WP_Query filters (posts_where, posts_join, etc.) become irrelevant or -- in some extreme situations -- conflicting.

The gist of what happens whn you use WP_Query( 'es=true' ) is that on pre_get_posts, the query vars are sent to a new instance of ES_WP_Query. The query vars are then replaced with a simple post__in query using the IDs which Elasticsearch found. Because the generated SQL query is far simpler than the query vars would suggest, a plugin or theme might try to manipualte the SQL and break it.

Action/Filter Using ES_WP_Query ES_WP_Query Equivalent Using WP_Query with 'es' => true
pre_get_posts No issues es_pre_get_posts Potential conflicts
posts_search N/A es_posts_search Should be N/A
posts_search_orderby N/A es_posts_search_orderby Should be N/A
posts_where N/A es_query_filter Potential conflicts
posts_join N/A Potential conflicts
comment_feed_join N/A Potential conflicts
comment_feed_where N/A Potential conflicts
comment_feed_groupby N/A Potential conflicts
comment_feed_orderby N/A Potential conflicts
comment_feed_limits N/A Potential conflicts
posts_where_paged N/A es_posts_filter_paged, es_posts_query_paged Potential conflicts
posts_groupby N/A Potential conflicts
posts_join_paged N/A Potential conflicts
posts_orderby N/A es_posts_sort Potential conflicts
posts_distinct N/A Potential conflicts
post_limits N/A es_posts_size, es_posts_from Potential conflicts
posts_fields N/A es_posts_fields No issues
posts_clauses N/A es_posts_clauses Potential conflicts
posts_selection N/A es_posts_selection Potential conflicts
posts_where_request N/A es_posts_filter_request, es_posts_query_request Potential conflicts
posts_groupby_request N/A Potential conflicts
posts_join_request N/A Potential conflicts
posts_orderby_request N/A es_posts_sort_request Potential conflicts
posts_distinct_request N/A Potential conflicts
posts_fields_request N/A es_posts_fields_request No issues
post_limits_request N/A es_posts_size_request, es_posts_from_request Potential conflicts
posts_clauses_request N/A es_posts_clauses_request Potential conflicts
posts_request N/A es_posts_request Potential conflicts
split_the_query N/A Potential conflicts
posts_request_ids N/A Potential conflicts
posts_results N/A es_posts_results No issues
comment_feed_join N/A Potential conflicts
comment_feed_where N/A Potential conflicts
comment_feed_groupby N/A Potential conflicts
comment_feed_orderby N/A Potential conflicts
comment_feed_limits N/A Potential conflicts
the_preview N/A es_the_preview Potential conflicts
the_posts N/A es_the_posts No issues
found_posts_query N/A Potential conflicts
found_posts N/A es_found_posts Potential conflicts
wp_search_stopwords N/A N/A
get_meta_sql N/A get_meta_dsl N/A
date_query_valid_columns No issues No issues
get_date_sql N/A get_date_dsl N/A

Note that in the "Using WP_Query with 'es' => true" column, "no issues" and "N/A" are not guaranteed. For instance, in almost every filter, the WP_Query object is passed by reference. If a plugin or theme modified that object, it could create a conflict. The "no issues" and "N/A" notes assume that filters are being used as intended. Lastly, everything is dependant on pre_get_posts. If a plugin or theme were to hook in at a priority > 1000, it could render everything a potential conflict.

Contributing

Any help on this plugin is welcome and appreciated!

Bugs

If you find a bug, check the current issues and if your bug isn't listed, file a new one. If you'd like to also fix the bug you found, please indicate that in the issue before working on it (just in case we have other plans which might affect that bug, we don't want you to waste any time).

Feature Requests

The scope of this plugin is very tight; it should cover as much of WP_Query as possible, and nothing more. If you think this is missing something within that scope, or you think some part of it can be improved, we'd love to hear about it!

Unit Tests

Unit tests are included using phpunit. In order to run the tests, you need to add an adapter for your Elasticsearch implementation.

  1. You need to create a file called es.php and add it to the tests/ directory.
  2. es.php can simply load one of the included adapters which is setup for testing. Otherwise, you'll need to do some additional setup.
  3. If you're not using one of the provided adapters:
    • es.php needs to contain or include a function named es_wp_query_index_test_data(). This function gets called whenever data is added, to give you an opportunity to index it. You should force Elasticsearch to refresh after indexing, to ensure that the data is immediately searchable.
      • NOTE: Even with refreshing, I've noticed that probably <0.1% of the time, a test may fail for no reason, and I think this is related. If a test sporadically and unexpectedly fails for you, you should re-run it to double-check.
    • es.php must also contain or include a class ES_WP_Query which extends ES_WP_Query_Wrapper. At a minimum, this class should contain a protected function query_es( $es_args ) which queries your Elasticsearch server.
    • This file can also contain anything else you need to get everything working properly, e.g. adjustments to the field map.
    • See the included adapters, especially travis.php, for examples.

More Repositories

1

wordpress-fieldmanager

Custom field types for WordPress
PHP
504
star
2

mantle

Mantle is a framework for building large, robust websites and applications with WordPress
PHP
84
star
3

searchpress

Elasticsearch integration for WordPress.
PHP
77
star
4

wp-redis

WordPress Object Cache using Redis.
PHP
61
star
5

rewrite-testing

A WordPress plugin to unit test your rewrite rules
PHP
45
star
6

wp-seo

A simple, straightforward SEO plugin for WordPress. Just the facts, Jack.
PHP
44
star
7

wp-components

Components are reusable building blocks.
PHP
42
star
8

revealjs-wp-theme

Power your reveal.js presentation with WordPress
JavaScript
42
star
9

irving

Irving is an integrated, React-based framework for building single-page applications. Irving gives you all the power of isomorphic JavaScript while allowing full control over component layouts with a content management system like WordPress.
JavaScript
42
star
10

hubot-code-review

A Hubot script for GitHub code review on Slack.
CoffeeScript
40
star
11

options-importer

Export and import WordPress Options
PHP
36
star
12

webpack-git-hash

Webpack plugin for versioning bundles and chunks with the hash of the last Git commit
JavaScript
35
star
13

wp-block-converter

Convert HTML into Gutenberg Blocks with PHP
PHP
34
star
14

sasslint-webpack-plugin

A webpack plugin to lint your SCSS/SASS code
JavaScript
33
star
15

ad-layers

Ad Layers WordPress Plugin
PHP
26
star
16

logger

A Monolog-based logging tool for WordPress. Supports storing log message in a custom post type or in individual posts and terms.
PHP
25
star
17

create-wordpress-plugin

A skeleton repository for Alley's WordPress Plugins
PHP
25
star
18

wp-asset-manager

Asset Manager is a toolkit for managing front-end assets and more tightly controlling where, when, and how they're loaded.
PHP
25
star
19

pest-plugin-wordpress

A Pest plugin for WordPress
PHP
24
star
20

fieldmanager-demos

A WordPress Plugin used for demonstrating Fieldmanager
PHP
23
star
21

mantle-framework

Mantle is a framework for building large, robust websites and applications with WordPress. Framework for https://github.com/alleyinteractive/mantle
PHP
22
star
22

stage-file-proxy

Mirror (or header to) uploaded files from a remote production site on your local development copy. Saves the trouble of downloading a giant uploads directory without sacrificing the images that accompany content.
PHP
21
star
23

wp-irving

WordPress companion plugin to develop on Irving.
PHP
18
star
24

load-more-posts

Add an ajax load more button to a post archive.
PHP
18
star
25

wp-alleyvate

Defaults for WordPress sites by Alley.
PHP
17
star
26

sasslint-loader

sass lint loader for webpack
JavaScript
17
star
27

meta-inspector

See your post, term, and user meta data.
PHP
16
star
28

sublime-text-php-wordpress

Sublime Text PHP replacement, which adheres to WordPress coding standards
PHP
16
star
29

photonfill

PHP
15
star
30

huron

A front-end tool to generate prototypes and style guides.
JavaScript
15
star
31

wordpress-simplechart

Create and render interactive charts in WordPress using Simplechart
PHP
14
star
32

simplechart

Create simple interactive data visualizations and embed them in any CMS. WordPress plugin at https://github.com/alleyinteractive/wordpress-simplechart
JavaScript
14
star
33

my-photon

PHP
14
star
34

wp-bulk-task

A library to assist with running performant bulk tasks against WordPress database objects.
PHP
13
star
35

wp-github-autodeploy

A WordPress Plugin to manage auto deployment with Git and GitHub
PHP
13
star
36

Paw-WordPressCodeGenerator

Paw Extension that generates PHP code for the WordPress HTTP API
CoffeeScript
13
star
37

rewrite-register

PHP
12
star
38

es-admin

PHP
12
star
39

wp-twitter-api

A simple plugin for interacting with the Twitter v1.1 API from your WP code.
PHP
11
star
40

wp-rest-api-guard

Restrict and control access to the REST API
PHP
11
star
41

clone-replace

Clone & Replace WordPress Plugin. Gives you the ability to clone posts, and replace posts. Together, you have a very powerful tool for a fork/merge editing model.
PHP
11
star
42

feed-consumer

Ingest external feeds and other data sources into WordPress
PHP
10
star
43

pusher-for-wordpress

Shell
10
star
44

alley-sitemap

A light, simple, fast, and flexible XML Sitemap Generator for WordPress
PHP
10
star
45

create-wordpress-project

A starter structure for the wp-content directory on a new WordPress project.
PHP
8
star
46

wp-curate

WordPress Curation Plugin
PHP
7
star
47

alley-coding-standards

Linting rules for Alley Interactive
PHP
7
star
48

debug-bar-remote-requests

An add-on for the WordPress Debug Bar to log and profile remote requests
PHP
7
star
49

reveal-template

Alley Interactive's reveal.js theme, along with a starter template
JavaScript
7
star
50

jquery-breakpoints

A simple jQuery plugin for managing breakpoints and change events
7
star
51

wordpress-autoloader

WordPress autoloader that follows WordPress coding standards
PHP
7
star
52

wp-experimental-features

A feature flags system for beta testing experimental features in WordPress.
PHP
7
star
53

archiveless

WordPress plugin to hide posts from archives (lists)
PHP
7
star
54

wp-path-dispatch

Simply and easily add a URL which fires an action, triggers a callback, and/or loads a template.
PHP
7
star
55

fm-zones

Fieldmanager field which acts as a Zoninator clone
PHP
6
star
56

fm-gutenberg

Fieldmanager Gutenberg
TypeScript
6
star
57

alley-scripts

A collection of scripts and utilities for Alley projects.
TypeScript
6
star
58

js-component-framework

JavaScript
6
star
59

wp-match-blocks

Match WordPress blocks in the given content.
PHP
6
star
60

wxr-validator

A WP-CLI command to validate WXR data
PHP
6
star
61

wp-component-library

A plugin to list and preview components from the active theme's component library in the WordPress admin.
PHP
6
star
62

csv-import-framework

PHP
6
star
63

wp-theme-migrator

A WordPress library to migrate to a new theme incrementally.
PHP
6
star
64

wp-doc-command

PHP
6
star
65

create-wordpress-theme

A template repository for creating a new block-based WordPress theme with an opinionated structure.
HTML
5
star
66

internal-flags

Use a hidden taxonomy to improve expensive queries.
PHP
5
star
67

expiring-posts

Automatically expire posts after a certain period of time. Checks the post's published and modified date to see if the post is expired and will perform an action on the post (draft/trash/delete it).
PHP
5
star
68

wp-caper

Fluently distribute capabilities to roles in WordPress.
PHP
5
star
69

fieldmanager-bylines

PHP
5
star
70

wp-new-relic-transactions

A companion plugin when using New Relic with WordPress, to improve the recorded transaction data
PHP
5
star
71

composer-wordpress-autoloader

Composer Autoloader that supports the WordPress Coding Standards
PHP
5
star
72

wp-block-audit-command

Audit WordPress block usage in post content.
PHP
5
star
73

wp-404-caching

Enables caching on 404 pages to prevent performance issues related to bad request flooding.
PHP
5
star
74

switchboard

PHP
4
star
75

wp-find-one

Query for and return one WordPress post, term, or other object, bypassing intermediate arrays.
PHP
4
star
76

speed-bumps

Port of Fusion's Speed Bumps. Intelligently insert speed bumps into site content.
PHP
4
star
77

publishing-checklist

Pre-flight your posts.
PHP
4
star
78

mantle-docs

Documentation for mantle.alley.co
MDX
4
star
79

create-mantle-app

A starter template for a WordPress project, rooted at `/wp-content/`.
CSS
4
star
80

wordpress-post-payments

WordPress plugin that tracks story cost and payment due totals
PHP
4
star
81

wp-filter-side-effects

Use a WordPress filter like an action.
PHP
4
star
82

wp-concurrent-remote-requests

Feature plugin for concurrent HTTP remote requests
PHP
4
star
83

wordpress-fieldmanager-sidebar

Create custom siders using the FM framework for individual posts
PHP
4
star
84

a-dashboard-notice

A simple WordPress plugin to display a notice to anyone viewing the Dashboard
PHP
4
star
85

wp-light-sessions

PHP
4
star
86

traverse-reshape

Safely break down arrays or objects, and put them back together in new shapes.
PHP
4
star
87

elasticsearch-extensions

Extensions to various Elasticsearch plugins to make it easier to implement common features like faceted search.
PHP
4
star
88

civil-first-fleet

WordPress theme for the Civil First Fleet
PHP
4
star
89

gsuite-provision

WordPress plugin to provide seamless user provisioning for a trusted GSuite domain
PHP
3
star
90

cache-collector

Dynamic cache key collector for easy purging
PHP
3
star
91

action-deploy-to-remote-repository

Sync to remote repository via GitHub actions
Shell
3
star
92

php-http-api

A standalone HTTP API extrapolated from WordPress
PHP
3
star
93

critical-style-loader

JavaScript
3
star
94

wp_enqueue_media_override

Override wp_enqueue_media to be more performant
PHP
3
star
95

byline-manager

Manage an article's byline and author profiles in WordPress.
PHP
3
star
96

wp-newsletter-builder

WP Newsletter Builder
PHP
3
star
97

wp-pdf-generator

PHP
3
star
98

alley-widgets

A collection of WordPress widgets by Alley Interactive
PHP
3
star
99

tmsconnect

TMS connectivity plugin
PHP
3
star
100

mailchimp-ajax

Subscribe to MailChimp lists without a crazy overloaded settings page
PHP
3
star