Skip to content


How-to Guides

Technical References

Enterprise Search /

Use Enterprise Search Locally


  • Basic understanding of WordPress development
  • Basic Git experience
  • A local machine capable of running Docker Desktop
  • Familiarity with the command line and code editing

Set up local environment

If you haven’t already, follow the steps to set up a VIP Local Development Environment. For this example, we’ll use Method B without an application ID and the slug name example-site.

1) After you’ve created and started the environment, log in to the backend with the default credentials:

Your local environment is now set up as an empty multisite (with one main site). Enterprise Search is currently not enabled for it.

2) Navigate to the home page:

After you have logged in, you will see the admin bar at the top.

1) Navigate to the vip-config directory.

cd ~/vipdev
cd vip-go-skeleton/vip-config

2) To enable both Enterprise Search and Search Dev Tools, add the code below to vip-config.php:

 * Enable VIP Search
define( 'VIP_ENABLE_VIP_SEARCH', true );
define( 'EP_IS_NETWORK', true );

 * Enable Search Dev Tools
define( 'VIP_SEARCH_DEV_TOOLS', true );

After completing the above steps, Elasticsearch is now enabled for your site. To test it out:

1) Reload the page with the search results:

2) Search Dev Tools will now appear in the admin bar:

The Search Dev Tools is to the right of Query Monitor.

3) Click the Search Dev Tools and expand the query:

The query results will be displayed in JSON format.

On the VIP Local Development Environment, Enterprise Search automatically starts in the background (not enabled yet) and existing posts at that time were indexed.

Testing indexing

1) To verify if indexing is working, publish a new test post with title of “New test post” and content “This post contains some words to search for. Who likes cheeseburgers? What about hot dogs?”.

2) Perform a search again with text that was in the new test post:

New test post returned from Elasticsearch in search result.

3) Use the CLI to check the health of the index with the validate-counts command.

vip --slug=example-site dev-env exec -- wp vip-search health validate-counts

The output from the command will display post counts for two different post types, post and page, and compare the count for each between the database (DB) and index (ES).

Validating post count

✅ no inconsistencies found when counting entity: post, type: post, index_version: 1 - (DB: 2, ES: 2, Diff: 0)
✅ no inconsistencies found when counting entity: post, type: page, index_version: 1 - (DB: 1, ES: 1, Diff: 0)

The health check above shows that there are no differences between the database and the index. This indicates that Enterprise Search is enabled and indexing is running correctly.

Enterprise Search and new subsites

1) Create a new subsite by navigating to “Sites” in the Network Admin:
and selecting “Add New”.

2) Complete the field prompts with the following values:

  • Site Address (URL): example-subsite
  • Site Title: Example Subsite
  • Admin Email: (or any email value of your choice)

3) Click on “Add Site“.

View of completed fields for “Add New Site”

4) Navigate to the home page of the site on the front end.

Enter the search term “hello” in the Search field.

Open the Search Dev Tools panel to view more information about the search results:

Search Dev Tools displays zero search results for the term “hello” on the new subsite.

Search Dev Tools shows that an index exists for the new subsite, but no posts have been indexed.

5) Use the CLI to check the health of the subsite index with the validate-counts command.

vip --slug=example-site dev-env exec -- wp vip-search health validate-counts

The health report indicates there are no posts in the subsite index:

Validating post count

🟧 skipping, because there are no documents in ES when counting entity: post, type: post, index_version: 1
🟧 skipping, because there are no documents in ES when counting entity: post, type: page, index_version: 1

6) Run the index command to sync the posts in the database with the index.

Note: When re-indexing a live production site, use versioning. Since this is a local environment with no live traffic, we will index as-is.

vip --slug=example-site dev-env exec -- wp vip-search index --setup
⚠️  You are about to run a destructive operation. Are you sure? [y/n] y
Adding post mapping…
Success: Mapping sent
Indexing posts...
Processed 2/2. Last Object ID: 1
Number of posts indexed: 2
Total time elapsed: 0.524
Success: Done!

7) Search for “hello” again in the subsite:

You will see a search result now.

8) The Search Dev Tools will also return a search result:

Offloading to WP_Query

Non-search queries are not offloaded to Enterprise Search by default. In order to offload them to Enterprise Search, you will need to modify WP_Query.

1) Generate some posts with content using the command line:

curl -N | vip --slug=example-site dev-env exec -- wp post generate --post_content --count=10

This generates 10 new posts with Lorem Ipsum content in our root site. The posts will be indexed immediately.

2) Repeat the same command with an older date using the --post-date option:

curl -N | vip --slug=example-site dev-env exec -- wp post generate --count=10 --post_type=post --post_date=1999-01-04

3) Navigate to the home page to view the newly generated posts:

Homepage with newly generated posts.

4) Navigate to the second page of posts:

5) Check the Query Monitor and look for the query that determines which posts show on the second page:

 FROM wp_posts
 WHERE 1=1
 AND wp_posts.post_type IN ('post', 'page')
 AND (wp_posts.post_status = 'publish'
 OR wp_posts.post_status = 'private')
 ORDER BY wp_posts.post_date DESC
 LIMIT 10, 10

If the query doesn’t show up, you may need to flush the object cache.

6) In the footer, the “Recent Posts” widget displays the latest five posts. The query for this widget can be found in Query Monitor:

SELECT wp_posts.ID
 FROM wp_posts
 WHERE 1=1
 AND wp_posts.post_type = 'post'
 AND ((wp_posts.post_status = 'publish'))
 ORDER BY wp_posts.post_date DESC
 LIMIT 0,5
Recent Posts footer widget.

The query for the “Recent Posts” widget and for the posts on the second page are usually relatively fast, but they can become slow on a site with a lot of posts and traffic.

7) On your local machine, navigate to the client-mu-plugins folder in the vip-go-skeleton directory and create a new file called search.php.

cd ~/vipdev/vip-go-skeleton/client-mu-plugins
touch search.php

8) Add the below code to search.php to use the pre_get_posts hook to offload both queries (e.g. not of the back-end or category type):


 * Offload to ES
function vip_sample_es_offload( $query ) {
	if ( is_admin() ) {
    if ( ! $query->is_category() ) {
        $query->set( 'es', true );
add_action( 'pre_get_posts', 'vip_sample_es_offload' );

9) Navigate to the homepage and click on the Search Dev Tools on the admin bar:

You will see two new Enterprise Search queries:

10) Refer to Query Monitor and locate the /* ES_WP_Query Shoehorn */ comment at the end of the query, which indicates that the query was generated by es-wp-query:

Query Monitor display of offloaded query to es-wp-query.

When Elasticsearch returns the list of post IDs that matched the query, the database is queried (via the “shoehorn”) to obtain the post data needed to construct the HTML result the user will see.

Elasticsearch queries will run first and any other MySQL queries (without the shoehorn comment) will run afterwards.

Cleaning up

The destroy command dismantles the local development environment:

vip --slug=example-site dev-env destroy

The code that was manually cloned earlier will remain in the ~/vipdev directory. To explicitly delete with a rm command:

rm -r ~/vipdev

Last updated: September 08, 2021