Filter hooks

Relevanssi has lots of filter hooks you can use to modify how the plugin behaves. Most of these are pretty advanced and an average user probably doesn’t have to worry about them, but if you’re going to do something more demanding, knowledge of these filters will help.

If you do something that would be made easier by a new filter, please let me know – I do like adding new filter hooks, as that is a very easy way to add flexibility to the plugin with little effort.

For more information on how to use filters, see WordPress Actions and Filter Hooks: A Guide for Non-Developers.

This list is not comprehensive: there are probably filters missing from the list. It’s often a good idea to check the plugin source code for the appropriate location to see if there’s a filter hook you could use.

relevanssi_1days, relevanssi_7days, relevanssi_30days ($days)
(Since 2.2.2) These filters can be used to adjust the number of days shown for the three panels of search logs. The default values are 1, 7, and 30, but if you want to show results for a different number of days, just adjust these filters and return the desired number of days for each box.

relevanssi_accents_replacement_arrays ($replacement_array)
Relevanssi uses str_ireplace() to replace accented characters with their non-accented variants in order to make excerpts and highlighting match both forms. This filter can be used to adjust how this replacement is done. The parameter array has two parts: “from” has the non-accented forms and “to” has the matching accented letters.

relevanssi_accept_mime_type ($read_this, $mime_type) (Premium only)
(Since 2.2.4) This fires for every attachment read. If $read_this is true, Relevanssi will read the attachment contents. You can use this filter to block certain MIME types from being indexed.

relevanssi_admin_search_capability ($capability)
(Since 2.2.1) This filter can be changed to adjust the default capability required to see Relevanssi settings. The default value is ‘edit_posts’ (ie. contributor level).

relevanssi_admin_search_ok (true, $query)
This filter can modify whether the default admin search query by WP is blocked or not.

relevanssi_allow_one_letter_highlights (false)
If you add a filter hook here that returns true, Relevanssi highlighting will highlight one-letter words. Otherwise one-letter words will not be highlighted.

relevanssi_attachment_server_url ($url)
(Since 2.2) Can be used to change the default attachment indexing server. See instructions here.

relevanssi_block_one_letter_searches (true)
If you want Relevanssi to process one-letter searches, add a filter to this hook and make it return false.

relevanssi_bots_to_not_log ($bots_array)
This filter can be used to prevents bots from being logged in the user searches blog. This filter expects an array with key => value pairs where key is the name of the bot and value the user agent of the bot.

relevanssi_clean_excerpt ($content, $start_emp_token, $end_emp_token)
(Since 2.1.7) This filter can be used to adjust highlights in excerpts, for example to clean out unwanted highlights inside elements. Highligts begin with $start_emp_token and end with $end_emp_token. After this filter, those tokens will be replaced with the actual tags used for the highlights.

relevanssi_comment_author_to_index ($author_name, $comment_id)
(Since 2.1.7) Comment author is passed through this filter before indexing. If you don’t want to index comment authors, add a filter on this function that calls __return_empty_string().

relevanssi_comment_content_to_index ($content, $comment_id)
Comment content is passed through this filter before indexing. You can use this filter to add any content to comments before they are indexed.

relevanssi_comparison_order ($array)
(Since 2.2.3) Provides the sorting order for the filter. The array should contain the possible key values as keys and their order in the values, like this: $order = array( 'post' => 0, 'page' => 1, 'book' => 2, ); This would sort posts first, pages second, books third. Values that do not appear in the array are sorted last.

relevanssi_content_to_index (”, $post)
You can use this filter to add extra content to posts before Relevanssi indexes them. The additional content is then trimmed and a space is added between the old content and the added content.

relevanssi_custom_field_value ($field_value, $field_name, $post_id)
(Since 2.0.3) This filter can be used to filter custom field values both before indexing and before excerpt-building.

relevanssi_custom_fields_to_index ($custom_fields)
Filters the list of custom fields before the custom fields are indexed. Can be used to add or to remove custom fields from the list of custom fields to index. For example if you want to use “visible”, but still skip some custom fields, you don’t have to list the ones you want to index: just have Relevanssi index all “visible” custom fields, then use this filter hook to filter out the unwanted ones.

relevanssi_default_meta_query_relation (‘OR’)
By default, Relevanssi assumes the meta query relation is OR. If you want to change the default relation to AND, you can use this filter hook to do so.

relevanssi_default_punctuation_replacement (” “)
(Since 2.0) While relevanssi_punctuation_filter handles most of the important punctuation, some fall outside that. The default behaviour is to replace those with spaces. If you want to instead remove them completely, you can add a function on this filter returning an empty string.

relevanssi_default_tax_query_relation (‘OR’)
By default, Relevanssi assumes the taxonomy query relation is OR. If you want to change the default relation to AND, you can use this filter hook to do so.

relevanssi_df_query_filter ($query)
Relevanssi calculates DF (document frequency) with a simple MySQL query. You can filter that query with this hook. Mostly useful if you modify the way fuzzy queries are done, in which case you’ll want to make the change to this query as well.

relevanssi_didyoumean_suggestion ($suggestion)
The whole suggestion – anchor tag, URL, suggestion text – is passed through this filter.

relevanssi_didyoumean_url ($url)
The URL produced by relevanssi_didyoumean() function is passed through this filter.

relevanssi_disable_shortcodes_excerpt ($shortcodes)
An array of shortcodes that are disabled before Relevanssi builds excerpts. The default value includes a bunch of shortcodes we’ve found not to play nice with Relevanssi excerpt-building.

relevanssi_do_not_index (false, $post->ID)
If this filter returns true, Relevanssi will not index this post. You can use this filter to selectively prevent posts from being indexed.

relevanssi_do_not_index_term (false, $term, $taxonomy) (Premium only)
(Since 2.0.4) The same as relevanssi_do_not_index, but for taxonomy terms.

relevanssi_do_not_read ($hide_post, $post_id) (Premium only)
(Since 2.2.4) The same as relevanssi_do_not_index, but for attachment content.

relevanssi_ellipsis (“…”)
If you want to replace the … in the end and beginning of excerpts with something else, use this filter.

relevanssi_entities_inside_code (boolean)
(Since 2.2) If set to the default value of true, code tag contents will be processed with htmlentities(). If false, the contents will remain unprocessed.

(Since 2.2) If set to the default value of true, pre tag contents will be processed with htmlentities(). If false, the contents will remain unprocessed.

relevanssi_excerpt ($excerpt, $post_id)
After the excerpt is generated, but before the ellipsis and highlighting is added, you can use this filter to modify the excerpt. The second parameter gives you the post ID.

relevanssi_excerpt_content ($content, $post, $query)
When Relevanssi builds excerpts, the post content passes through this filter, after it goes through relevanssi_pre_excerpt_content and the_content. All these filters give you a chance to add more content to the post to work as a building block of excerpts. For example, if you want custom field content to appear in the excerpts in case the search term is found in a custom field, use this filter or relevanssi_pre_excerpt_content to simply concatenate the custom field content to the end of the post content – the excerpt building algorithm will find it there.

relevanssi_excerpt_custom_field_content ($content)
(Since 2.0) Filters the custom field content that is used as material for building excerpts. If you want to clean out the content, regenerate it in a particular way or something like that, this filter hook is helpful.

relevanssi_excerpt_query ($query)
(Since 2.0.4) Filters the search query before excerpt is built.

relevanssi_fallback ($params)
(Since 2.0) When Relevanssi finds no results, there can be a fallback search (like when AND searches fall back to OR searches). This filter can be used to perform other fallback searches. It gets the search parameters in the parameter array, see $params[‘args’]. The filter needs to run the search (in any way you see fit) and put the return values in $params[‘return’]. The format should match what relevanssi_search() returns.

relevanssi_fuzzy_query (“(relevanssi.term LIKE ‘#term#%’ OR relevanssi.term_reverse LIKE CONCAT(REVERSE(‘#term#’), ‘%’)) “)
This filter lets you modify the way Relevanssi runs the fuzzy queries. The main thing you can do here is to change this value to “(term LIKE ‘%#term#%’) ” to make it match search term completely inside words. By default the search term in fuzzy search must match either beginning or the end of a word. #term# will be replaced by the actual search term later.

relevanssi_get_words_having ($c) (Premium only)
(Since 1.15.2) Relevanssi Premium uses a “Did you mean” function that needs to know all the words in your database. This, however, can be problematic once your search index grows large enough. To fix that, you need to prune out rarer words to make the amount of data smaller. This can be done using this hook. See “Did you mean” suggestions, the solution is in the end of the article.

relevanssi_get_words_query ($query) (Premium only)
(Removed in 1.15.2) Relevanssi Premium uses a “Did you mean” function that needs to know all the words in your database. This, however, can be problematic once your search index grows large enough. To fix that, you need to prune out the words that appear only once to make the amount of data smaller. This can be done using this hook. See “Did you mean” suggestions, the solution is in the end of the article.

relevanssi_hide_empty_terms (true) (Premium only)
(Since 2.0.2) By default Relevanssi doesn’t index taxonomy terms that are not connected to any posts. Have this filter return false to include the empty terms as well.

relevanssi_hits_filter (array($hits, $query))
This is one of the most powerful filters in Relevanssi. It lets you modify the array $hits, which contains all the hits Relevanssi found. The hits are post objects, which makes manipulating them easy. At this point, you can reorder the search results at will, remove them, add new and so on. The parameter array also contains the search query, which Relevanssi doesn’t need back, it’s just there for reference in case you need it. Remember to return the array of posts like this: array($hits).

Relevanssi filter functions on this hook:
– relevanssi_wpml_filter() (default priority) adds WPML language support

relevanssi_index_comments_exclude (false, $post_id)
If this filter returns true, Relevanssi won’t index the comments for the $post_id mentioned in the second parameter.

relevanssi_index_content (true)
If this filter returns false, Relevanssi won’t index content of posts or pages.

relevanssi_index_custom_fields ($custom_fields)
The filter is given a list of custom fields before the custom fields are indexed. Feel free to manipulate the list as you wish. This can be useful for selecting the indexed custom fields with a regexp, for example.

relevanssi_index_taxonomies_args ($args) (Premium only)
(Removed in 2.0.2) When Relevanssi indexes taxonomy terms, it uses get_terms() to get the terms. By default Relevanssi uses the default arguments, but you can use this filter to modify that. One example case would be setting “hide_empty” to false to get the terms that are empty.

This filter has been removed. The taxonomy term indexing doesn’t use get_terms() anymore. The behaviour is still similar, and you can use relevanssi_hide_empty_terms to enable the empty terms.

relevanssi_index_titles (true)
If this filter returns false, Relevanssi won’t index titles of posts or pages.

relevanssi_indexing_data ($data, $post)
Post data is passed through this filter before it is formed into MySQL value strings.

relevanssi_indexing_restriction ($restriction)
(Since 4.0.9 / 2.1.5) This filter can be used to add extra restrictions to the MySQL query used to fetch the posts to index. This is useful if you have lots of posts and a many posts are being excluded from the index. Using relevanssi_do_not_index can get clumsy in those situations, and will have to sift through lots of unwanted posts. Setting the restriction from this filter hook, if possible, lets Relevanssi skip those posts right away. The $restriction will be inserted in a MySQL query in the WHERE clause, so it has to be valid MySQL (see relevanssi_generate_indexing_query() in lib/indexing.php).

relevanssi_indexing_values ($data, $post)
Post data is passed through this filter before it is inserted into the database. In many cases, relevanssi_indexing_data is easier to use.

relevanssi_join ($data)
This can be used to JOIN tables to the Relevanssi search queries.

relevanssi_log_get_user ($user)
This filter is passed the user object in relevanssi_update_log(), before the function checks if the user should be logged or not.

relevanssi_match ($match, $idf, $term)
Another powerful filter. This lets you modify the $match objects, which are used to calculate the weight of the documents. The object has attributes which contain the number of hits in different categories. Post ID is $match->doc, term frequency (TF) is $match->tf and the total weight is in $match->weight. The filter is also passed $idf, which is the inverse document frequency (IDF). The weight is calculated as TF * IDF, which means you may need the IDF, if you wish to recalculate the weight for some reason. The third parameter, $term, contains the search term.

relevanssi_missing_sort_key ($value, $key)
When Relevanssi tries to sort posts and there’s no value for the key in the post (this can happen when sorting by menu_order), you can use relevanssi_missing_sort_key to set a default value. The value is returned as $value and the $key holds the name of the key used to sort. Here’s an example of setting the default value when sorting by menu_order:

add_filter('relevanssi_missing_sort_key', 'rlv_set_key', 10, 2); 
function rlv_set_key($value, $key) { 
    if ($key == "menu_order") $value = PHP_INT_MAX; 
    return $value; 

relevanssi_modify_wp_query ($wp_query)
If you want to make some changes in the query before Relevanssi sees it, you can use this filter hook to modify the $wp_query variable before it is passed to Relevanssi. This is a good place, for example, to combine query variables. You can for example have one input field for positive search terms and another for negative search terms and then use this filter to combine them both into the ‘s’ query variable where Relevanssi will look for the search terms.

relevanssi_multisite_public_status ($status, $blog_id) (Premium only)
(Since 2.0.2) When doing a multisite search, by default Relevanssi doesn’t search within blogs that aren’t public. If you want to include non-public blogs within the search, have this filter return `true` for the appropriate blog ID.

relevanssi_ok_to_log (true, $query, $hits, $user_agent, $ip)
This filter can be used to block queries from being logged. Return false to prevent a query from being logged. $query has the query, $hits is the number of hits, $user_agent is the user agent string and $ip has the user IP address, if it’s being recorded.

relevanssi_optimize_excerpts (false)
(Since 2.0) If this filter returns true, Relevanssi will build the excerpts faster. This means that the best possible excerpts may not be generated, if the best content is in the end of a long post, but the excerpt-building will be much faster.

relevanssi_options_capability (‘manage_options’)
This filter can be changed to adjust the default capability required to see Relevanssi settings. The default value is ‘manage_options’.

relevanssi_order ($order)
Use this filter to modify the order parameter before Relevanssi sorts posts.

relevanssi_orderby ($orderby)
Use this filter to modify the orderby parameter before Relevanssi sorts posts.

relevanssi_page_builder_shortcodes ($array)
(Since 2.0) Relevanssi removes some Divi and Visual Composer page builder shortcodes from excerpts. This filter can be used to add or remove shortcodes from the list.

relevanssi_pdf_read_timeout (45) (Premium only)
(Since 2.0.2) By default, the PDF reading timeout is set to 45 seconds. You can use this filter to adjust it higher, in case you’re seeing lot of timeout errors.

relevanssi_post_content ($content, $post)
Post content is passed through this filter before indexing. You can use this filter to add any content you wish to posts before they are indexed.

relevanssi_post_content_before_tokenize ($content, $post)
Post content is passed through this filter just before it’s tokenized. You can use this filter to add content to posts before they are indexed.

relevanssi_post_ok ($post_ok, $post_ID)
Can this post be included in the search results? This is the hook you’ll use if you want to add support for a membership plugin, for example. Based on the post ID, your function needs to return true or false.

Relevanssi filter function on this hook:
– relevanssi_default_post_ok (priority: 9) contains the default logic. If you want to override this, either remove this function from the hook (and make sure you cover the cases for private posts or drafts, see the default function for more details) or run yours after this on a lower priority.

relevanssi_post_title_before_tokenize ($post_title)
This filter allows modifications to post titles before they are tokenized.

relevanssi_post_to_index ($post)
Gives access to the post object before Relevanssi indexing sees it.

relevanssi_pre_excerpt_content ($post->post_content, $post, $query)
When Relevanssi builds excerpts, the post content passes first through this filter. Then it’s passed to the_content, then relevanssi_excerpt_content. All these filters give you a chance to add more content to the post to work as a building block of excerpts. For example, if you want custom field content to appear in the excerpts in case the search term is found in a custom field, use this filter or relevanssi_excerpt_content to simply concatenate the custom field content to the end of the post content – the excerpt building algorithm will find it there.

This is an action hook that runs before the main indexing query. This is a fairly large query and can go over the MAX_JOIN_SIZE set on the server. If that is the case, you can use this action hook to run “SET OPTION SQL_BIG_SELECTS=1” on the MySQL server to allow the large join.

relevanssi_premium_tokenizer ($token) (Premium only)
This hook is used to enable the stemmer in Premium. This filter sees every token (word) as it comes through the tokenizer, so you can use it for something else as well.

Relevanssi filter function on this hook:
– relevanssi_enable_stemmer (default priority, by default does nothing)

relevanssi_punctuation_filter ($replacement_array)
(Since 2.0) The Relevanssi default behaviour for punctuation removal is defined in an array that is passed through this filter hook. For most changes, it is not required to create a filter function on relevanssi_remove_punctuation, just changing the contents of this array is enough.

relevanssi_query_filter ($query)
This is your final chance to modify the main Relevanssi query before it is run on the database. This is also useful for echoing out the query when doing debugging.

Relevanssi filter function on this hook:
– relevanssi_limit_filter() (default priority) adds the LIMIT parameter

Relevanssi uses a hooked function to remove punctuation from search queries and documents. Some punctuation is replaced with spaces, some simply removed. If you’re interested in how this works, take a closer look at relevanssi_remove_punct() function in lib/common.php. If you want to change some of the behaviour, just unhook the default function and replace it with your own.

Relevanssi filter function on this hook:
relevanssi_remove_punct (default priority)

relevanssi_remove_stopwords_in_titles (boolean)
Filters whether stopwords should be removed from titles in tokenizing or not. Default value is true.

relevanssi_results ($results)
This filter lets you modify an array that contains (post_ID => weight) pairs. If unmodified, Relevanssi will fetch these posts and return them as the final search results (to another Relevanssi function, which will then take a slice of the array, as determined by how many posts are shown per page and which page of search results the user wants).

relevanssi_search_again ($params)
(Since 2.0) Relevanssi can rerun the search if no results are found. This filter hook can be used to adjust the search parameters between the runs, if you for example want to adjust the search terms between the queries. The parameter array contains five parameters: ‘no_matches’ which is set to true if nothing was found, ‘doc_weight’ which has the weights of the found posts, ‘terms’ which has the search terms, ‘o_term_cond’ which has the term matching pattern and ‘search_again’ which needs to be set to true if you want to run the search again.

relevanssi_search_filters ($array)
This filter lets you manipulate search parameters before Relevanssi uses them. The array contains following keys: ‘q’, ‘cat’, ‘excat’, ‘tag’, ‘expost’, ‘post_type’, ‘taxonomy’, ‘taxonomy_term’, ‘operator’, ‘search_blogs’, ‘customfield_key’, ‘customfield_value’, ‘author’.

relevanssi_search_form ($form)
(Since 2.2.4) Filters the search form HTML code generated by the searchform shortcode.

relevanssi_search_ok ($search_ok)
Relevanssi is activated always when posts are requested. Thus, Relevanssi needs to figure out if it’s an actual search, before taking action. If is_search() is true, it’s a search. If is_admin() is true, then Relevanssi will reconsider and so on. You can modify this behaviour with this hook, which is fired after Relevanssi has checked other cases. By returning a true here, you’ll force Relevanssi to become active. This is mostly useful when using Relevanssi without a search term where you’ll trigger Relevanssi based on active query variables.

relevanssi_show_matches ($matches)
If you use the “Show breakdown of search hits in excerpts” option, this filter lets you modify the breakdown before it is added to the excerpt.

relevanssi_stemmer ($token) (Premium only)
This hook is used to add a stemmer (or anything else that needs to process every search term and indexed word). Relevanssi Premium comes with a simple English stemmer (actually a suffix stripper), which you can enable:

add_filter('relevanssi_stemmer', 'relevanssi_simple_english_stemmer');

relevanssi_tag_before_tokenize ($content)
Use this filter to modify tag content before Relevanssi tokenizer sees it.

relevanssi_term_add_data ($term, $taxonomy) (Premium only)
Use this filter to add extra data to taxonomy term objects before they are indexed.

relevanssi_tax_term_additional_content ($description, $term) (Premium only)
Taxonomy term description is passed through this filter before indexing, so you can add any content you wish to taxonomy term descriptions.

relevanssi_user_add_data ($user) (Premium only)
Use this filter to add extra data to user objects before they are indexed.

relevanssi_user_searches_capability (‘edit_pages’)
The capability level required to access the User Searches page.

relevanssi_valid_status ($statuses)
By default, Relevanssi indexes posts with a status of “publish”, “draft”, “private”, “pending” and “future” (not all of these posts are displayed to front end users). If you want to modify the statuses, you can do it with this filter.

relevanssi_where ($query_restrictions)
The way Relevanssi works is to search for the terms in the index, with a bunch of restrictions to restrict the search to certain post IDs (or to exclude particular post IDs). This filter gives you a chance to examine and modify those restrictions before they are used.

relevanssi_woocommerce_indexing (array)
(Since 4.0.9 / 2.1.5) This can be used with WooCommerce 3 to exclude products from Relevanssi indexing based on WooCommerce product visibility. See instructions in this KB entry.

90 comments Filter hooks

  1. Hello,
    Thank you for such a great plugin and your awesome support !

    I am using the networked version using a child theme from Twenty Eleven and WordPress 3.4.2 with Relevanssi Premium. Everything is working perfectly and I have implemented highlighting with css styling, “Did You Mean”, automatic indexing and stemming.

    The question I have is: how to I save the state of a not found search term?
    For example: I search for the term “spacewalk” and it is not found, so
    I do not want to retype, I just want to edit the term “spacewalk” to “space walk”

    I assume it is some sort of modification to the search.php file.

    Any help would be greatly appreciated.


  2. hi, what if i’d like to make a multiple pulldown filter so i can choose objects first by tipology, then after that by designer and so on? is there any way to achieve that? 🙂

  3. I am having some difficulty finding examples to back up this documentation. Are there any examples of filters being use that I just am not seeing?

    I have the premium version, and would like to be able to give users search options, so they can adjust the weight at search time. For example, one user may want to search everything. Another may want to limit their search to the “Artists” taxonomy (or make the weight of that taxonomy higher while lowering the weight of post titles an descriptions. Then a third user may want to search just track titles.

    Maybe adjusting the weight is not the right approach, and there is some other aspect of the filters that should be using?

    I have my Relevanssi indexing everything, so how do I apply the filters base on user-selected options in the search form? Any example code I can see? Any sites that actually do this kind of thing? I just can’t find anything,

    1. If you want to use taxonomy filters, the best way is to create a tax_query ( and add it with relevanssi_modify_wp_query. Here’s a fairly thorough example. Doing a taxonomy dropdown is fairly easy (wp_dropdown_categories() helps a lot).

      If you want to adjust weights, then you must use the relevanssi_weight filter; the approach is similar, read the user-provided values from query variables and use them in the filter. I think that’s too much control to give for users: it’s lots of work for you to write, and 99.99% of users will never use it.

      Searchers in general just want to type words, anything more advanced is unlikely to see use.

      1. How people will want to search will depend on the context. In my case I am indexing a second-hand record store. Depending on what they are searching for, they may want to lean towards a specific artist (in the artist taxonomy) or more towards a genre of music. They won’t be searching through big articles of text, but being able to find an artist that has been spelt ten different ways, will be very useful.

        So if I understand correctly, I nee to write my own query form and back-end, using the standard WordPress techniques, and Relevanssi will kick in and direct the query towards its own indexes? Or have I misunderstood?

          1. I’ve not had any luck at all. I have tried adding a tax_query, as shown in your example link, and nothing is getting filtered. The example is quite a few years old now – is it still correct?

            I have this in my custom_search_filter:

            $query->set(‘tax_query’, array(
            ‘taxonomy’ => ‘artist’,
            ‘terms’ => array(‘foobar’),
            ‘field’ => ‘slug’,
            ‘operator’ => ‘IN’,
            ‘relation’ => ‘AND’,

            There is no “foobar” slug in the artist taxonomy, so I would expect everything to be filtered out, but no filtering is happening at all.

            If I can get this working, I don’t see any mention in documentation of WP_Tax_query supporting wildcards on taxonomy term names or slugs. Is that supported, since it is central to my original problem?

          2. Looks like you’re one array too shallow: wrap your array() in one more array() and it should work.

            No wildcards in tax_query, it’s an exact match system.

          3. Adding an array wrapper makes no difference. The query appears in the $query->query_vars array like this:

            array(1) {
            array(5) {
            string(6) “artist”
            array(1) {
            string(6) “foobar”
            string(4) “slug”
            string(2) “IN”
            string(3) “AND”

            The fact that taxonomy terms cannot be searched using wildcards kind of defeats the main object of what I am trying to do. The user enters terms to search, and one option is for them to retrieve products that have taxonomy terms that match the keywords they have entered. I guess I am going to have to do a separate query to fetch a list of term IDs and then inject the IDs into the taxonomy filter (if I can get it to work).

          4. Well, you can always use Relevanssi to search the taxonomy terms, then you can have wild cards. Tax_query is meant for dropdowns and exact match filtering anyway.

          5. I thought I *was* using relevanssi using this filter? I’m confused.

            Back to the beginning: I would like the user to be able to enter keywords into a search box, and those keywords to be used to match against taxonomy terms in a custom taxonomy, and return all posts (type products) for those matching taxonomies.

            Can relevanssi, having indexed the taxonomies, support this, or not?

          6. No – if you use tax_query, you’re not using Relevanssi. It is a direct MySQL query used to filter the results.

            What you need is automatically done, all you have to do is to check couple of boxes on Relevanssi settings to make Relevanssi index and search the taxonomies you want to search. Then all your searches will be checked against those taxonomies. No need to mess with tax_query.

          7. Sorry, I thought relevanssi took what was given to the query, with any additions added to the query in the relevanssi_modify_wp_query filter then formed its own query based on what it was given. I must have misunderstood.

            If I set the global settings to only search in a single taxonomy, then what do I do for the next user that wants to search in a different taxonomy, and the user after that who wants to search in titles and post bodies? How do I change those search options per search, depending on what search options the user has ticked?

          8. That’s a global setting, which you can’t modify per-user basis. Is it a huge problem if all searches match all taxonomies, post titles and bodies?

          9. Yes, it is a problem, because it is not what the client wants. They can use Google for a one-search-fits-all. We are indexing locally using Relevanssi because we need more control.

          10. I’ve worked around this problem now. When the search form is submitted with a second button called “artist_search”, that disables Relevanssi (two filters removed), empties the search term so it searches everything, fetches IDs of all the artist taxonomies that match the entered search term, adds those IDs into the query as a taxonomy join, then that fetches all products related to any taxonomy term that contains the artist name. Using the normal search button, and none of that happens so Relevanssi searches everything.

  4. Hi, I am having issues getting relevanssi to use the AND relation when searching by both a custom tax and a category. what is the proper way to implement relevanssi_default_tax_query_relation?

    I have tried : add_filter(‘relevanssi_default_tax_query_relation’, ‘AND’);

    but nothing changes. I also tried to add it in a function simply as relevanssi_default_tax_query_relation (‘AND’); and that gives the white screen of death.

    Any help is much appreciated

    1. You need to add a function to that filter, and that function needs to return “AND”. Like this:

      add_filter(‘relevanssi_default_tax_query_relation’, ‘isayand’);

      function isayand($relation) {
      return “AND”;

  5. I am trying to use your “relevanssi_pre_excerpt_content” or “relevanssi_excerpt_content” hook to modify the search results, but I cannot seem to access the post information inside my function… here is what I have currently…:

    add_filter(‘relevanssi_pre_excerpt_content’, ‘specificResults’);

    function specificResults($content, $post, $query) {

    return $post->ID;


    Any help on how to get the post content for the search result would be helpful.


    1. What are you trying to achieve here? At least the filter function should return the $content variable, after the modifications you’ve done to it. If you return the post ID, you’ll ruin the whole excerpts.

      1. Yes I understand it would ruin the excerpts, that was just me testing trying to get to the post content. What I am hoping to do, is that I have some LONG tabular data with product information on a few pages of the site I am working on for my client. If able to access the Post content I was planning on detecting the post ID, if it matched those with the product tables, then iterate through the content and present each table row in the results with a link taking the client to an anchor tag for the row they had searched for.

        The function reference above lists the $post as being passed through to the filter… but I cannot seem to access it.


        1. Ah, I know what your problem is. Your add_filter() call is missing the last two parameters, and because of that, only the first parameter is actually being passed to the function.

          add_filter(‘relevanssi_pre_excerpt_content’, ‘specificResults’, 10, 3);

          should work much better.

          Do note that whatever data you put in the content in relevanssi_pre_excerpt_content will get mangled by Relevanssi excerpt-building algorithm.

          1. Thank you Mikko, I am now able to access the Post data!

            One more question if you will indulge me, is there a way to disable the excerpt size limit from within the filter? or is there another filter hook that would give me access to that?

  6. I’m trying to use relevanssi_default_meta_query_relation to change the meta query relation to “OR” from the default of “AND” that I have set in the admin panel, but Relevanssi returns zero results. Here’s my code snippit:

    add_filter(‘relevanssi_default_meta_query_relation’, ‘isayor’);
    function isayor($relation) {
    return “OR”;

    I modified code that you posted in answer to another persons question. I want to leave the default set to AND, but under certain circumstances, switch to using OR.

    Thanks for your help!

  7. Does the relevanssi_default_tax_query_relation works in the free version?

    I see no change in if i use this code or not in the sql query string

    add_filter(‘relevanssi_default_tax_query_relation’, ‘relationAnd’);
    function relationAnd($relation) {
    return ‘AND’;

    i need a search for the query and two taxenomys where the post has to be in both custom taxenomies

  8. One feature request — the ability to filter output of relevanssi_didyoumean. Defaults to “$pre<a href=”$url”>$suggestion</a>$post”, but it would be really helpful to be able to filter the result to show as not just a link, or to add classes to the link. I’ve had to do both, and usually achieve these results through creative (and unsemantic!) JS/CSS hacks.

  9. Hey Guys, just doing an evaluation here. I can’t find clear documentation anywhere on this matter so hopefully someone can clarify. In my use case, I have a complex taxonomy with a tree of about 6 categories, each with 5-50 subcategories. We want to offer the user the ability to have an amazon or linkedin like filtering experience. So the two features we are looking for are:

    a. Start with a search query and then apply filters using checkbox. User should be able to apply multiple filters from the taxonomy. These should be AND filters. How would you go about doing this?

    b. User should be able to simply browse the categories and apply filters WITHOUT a search term. In this case, user is simply drilling down and selecting check boxes from the taxonomy to apply a filter. No search term would be required. These would also be AND filters. How would you do this?

    Are these two things possible? How much custom coding would this require. We’ll hire someone to do it but if it’s highly complex, it might be better to use ElasticSearch.

    Thanks in advance!

  10. I’m trying to use the relevanssi_didyoumean_url filter, and there is one bit that I’m having trouble with. I need the url to be I added the following to my theme’s functions.php file:

    add_filter('relevanssi_didyoumean_url', 'rlv_modify_url');
    function rlv_modify_url($url) {
    $url = get_bloginfo('url') . '/video/';
    $url = esc_attr(add_query_arg(array(
    '_sf_s' => urlencode($closest)
    ), $url ));
    return $url;

    Everything except the urlencode($closest) bit is working. What can I use instead to pull the search term into the filter properly?

  11. Hello, I want to change the AND relation to OR in the following sql, i want to filter if the string in the post content or in the metaquery. How can i change it ?

    string ‘SELECT relevanssi.*, relevanssi.title * 5 + relevanssi.content + relevanssi.comment * 0.75 + relevanssi.tag * 0.75 + * 0 + + relevanssi.category * 0.75 + relevanssi.excerpt + relevanssi.taxonomy + relevanssi.customfield + relevanssi.mysqlcolumn AS tf
    FROM wp_relevanssi AS relevanssi INNER JOIN wp_postmeta ON ( relevanssi.doc = wp_postmeta.post_id ) WHERE (term LIKE ‘%test’ OR term LIKE ‘test%’) AND (
    ( wp_postmeta.meta_key = ‘_itg_pre_requisites’ AND wp_postmet’… (length=653)

      1. if i use $query =str_replace(“AND (“, “OR (“,$query); in relevanssi_query_filter this will not affect the filtering in the future?

  12. Hello,
    I edit the relevanssi search query using relevanssi_query_filter filter as follow :
    SELECT relevanssi.*, relevanssi.title * 5 + relevanssi.content + relevanssi.comment * 0.75 + relevanssi.tag * 0.75 + * 0 + + relevanssi.category * 0.75 + relevanssi.excerpt + relevanssi.taxonomy + relevanssi.customfield + relevanssi.mysqlcolumn AS tf
    FROM wp_relevanssi AS relevanssi
    LEFT JOIN wp_postmeta
    ON ( relevanssi.doc = wp_postmeta.post_id )
    WHERE relevanssi.term = ‘sql’
    OR ((wp_postmeta.meta_key = ‘pre_requisites’
    AND wp_postmeta.meta_value LIKE ‘%sql%’ )
    OR (wp_postmeta.meta_key = ‘audience’
    AND wp_postmeta.meta_value LIKE ‘%sql%’ )
    OR (wp_postmeta.meta_key = ‘course_id’
    AND wp_postmeta.meta_value LIKE ‘%sql%’ ))

    This query take 5.2057 seconds
    note that the wp_relevanssi contain 3718 rows.
    Why the query take long time execution ?

  13. Hello,

    How i can know the location of hits, in other word how can i know if the hit in the title of the post or description ?


  14. There is a filter to add a simple English stemmer, and Relevanssi has WPML support. Is it possible to add a second stemmer and let the stemmers operate on posts in their language only? Currently, my Dutch terms are being stemmed as well, with incorrect results.
    NB: The simple English stemmer turns “wordpress” into “wordpr”.

    1. Nope, not really possible. In multilingual cases it’s best not to stem at all. Relevanssi could stem English posts with an English stemmer and Dutch posts with a Dutch stemmer, but Relevanssi can’t tell which language the user is using and doesn’t know which stemmer to use for search queries.

      Yes, “WordPress” becomes “wordpr”. That’s correct, if not very logical. That’s why it’s called a simple stemmer. A proper Snowball stemmer wouldn’t do anything to that, I think.

  15. Is it possible to search with AND and then OR so If I look for Red Blue trainers , it shows red, Blue trainers and then shows all red trainers, blue trainers and then anything with red, blue or trainers.


      1. Firstly you’re response times are amazing!
        Secondly, Brilliant thank you.
        So I add the filter from that link to functions.php

        In the relevassi settings do I need to set the default operator for the search to AND or OR with this please.

  16. Hi team,

    I am using your plugin on one of my website

    I would like to set the ‘SET OPTION SQL_BIG_SELECTS=1’ while user performs the search on my site.

    I try to use action hook as mentation on

    You can check my code below.

    function relevanssi_pre_indexing_query_action_hook( ) {
    global $wpdb;
    $wpdb->query(‘SET SQL_BIG_SELECTS=1’);
    add_action( ‘relevanssi_pre_indexing_query’, ‘relevanssi_pre_indexing_query_action_hook’ );

    But this code doesn’t have any effect.
    Can you guide me how to write the action hook or where I am making mistake?

    Looking forward to the positive response.

    Kind regards,

    1. As the name suggets, relevanssi_pre_indexing_query runs before indexing. It doesn’t run when searching. You can use pre_get_posts to do actions before Relevanssi is run in searches.

  17. Can you provide an example of how one would use relevanssi_fallback in functions.php? I can’t seem to figure it out. Here’s the best I can come up with:

    add_filter( ‘relevanssi_fallback’, ‘fallback_search’ );
    function fallback_search( $args ) {
    $args[‘args’][‘q’] = “pictures”;
    return $args;

    1. Jonathan, let’s ask it this way: what do you want to achieve? Your function needs to run the search, so just adjusting the parameters is not enough. If you want to search for “pictures” if the default search doesn’t find anything, the function would look like this:

      add_filter( 'relevanssi_fallback', 'fallback_search' );
      function fallback_search( $params ) {
          $params['args']['q'] = 'pictures';
          $params['return']    = relevanssi_search( $params['args'] );
          return $params;
      1. Ahh, that does it. I wasn’t sure how to actually run the search. Though I guess what I really want to do is hook into the script after it writes out its output, so I can show some custom content.

        For example, I can use the “the_content” filter to add stuff to the page before or after a post. How can I hook into Relevanssi and output custom content after the search results (especially if there are no results)?

        1. Jonathan, you don’t hook into Relevanssi for that. The output is something your theme does, so you need to modify your theme search results template. Just add the content to the search results template.

  18. I need some help!
    What i want is to intercept the results of a search, and using only the postID’s of the result-posts to create my own layout that would suit the layout of my other pages in my website (
    I tried this with no results 🙂

    function zoekresultaat($results) {
    foreach ($results as $post) {
    return $post->ID;

    Can any help me with a solution?

    1. Are you sure you want just the post IDs? In most cases, when replacing the search results template, you start from a post loop which uses the whole post objects. If the first thing you’d do with the post ID is to fetch the post object, just use the post objects. Saves time and effort.

      But if you really want just the post IDs and know what you’re doing, you can make Relevanssi return post IDs with this bit of code:

      add_filter( 'relevanssi_modify_wp_query', 'rlv_just_ids' );
      function rlv_just_ids( $query ) {
          $query->set( 'fields', 'ids' );
          return $query;

      Now Relevanssi will return you an array of post IDs instead of post objects. But I’m pretty sure you really want the post objects.

      1. Thank you very much, Mikko… For me the array of postid’s will do, I think 🙂
        I like to display the results just with some special information about the individual posts: picture, title, author and link.

        Will let you know if I will manage that!
        Thanks for your swift response!!!

        Kind regards,
        Hans Stavleu

  19. Put this into my functions.php:

    add_filter( ‘relevanssi_modify_wp_query’, ‘rlv_just_ids’ );
    function rlv_just_ids( $query ) {
    $query->set( ‘fields’, ‘ids’ );
    foreach ($ids as $id) {
    $post_title = get_the_title($post_id);
    echo $post_title;
    return $query;
    still getting the same output as before.

    I guess i am thinking the wrong way.


    1. Yes, you are. I would recommend hiring a WordPress developer to build this for you. If that’s not possible, then the first step is to study how the WordPress template hierarchy and post loops work.

      The function I gave you is complete; that’s all it takes to have Relevanssi give you post IDs. Don’t modify that.

      The results are not printed out in the Relevanssi filters. That’s the job for the search results template. You will need to have a post loop in the search results template, and there you can modify the way the results show up.

      Looking at what you’re trying to do here, you really should be using the post objects, like I said – then you can just echo $post->post_title, instead of having to call get_the_title(). You’re only making life harder for yourself by using the post IDs, it’s not helping you.

      But you’re pretty far off right now. Go read this: It should help you understand how the post loop works.

      1. Thank you very much, I understand what you said!
        I am not really in the circumstances to hire someone for my hobby project. But I now know where i have to find the solution 🙂

        Kind regards,

  20. Thank you very much for all your effort to help!
    That function does exactly what i was looking for 🙂
    Implementation went smoothly! Got it working within a few minutes.

    Thanks, Mikko!

  21. Not sure if this is the correct thread to post on, but here is my question. I am running a multisite, with subsites like a social network. In the social network, “posts” are created by each user on the network and it is not the traditional posts of wordpress which makes a search a bit different. I am hoping to create a search that includes content from user profile fields (name, location, etc…) as well as searchable content from each user’s posts. Can this be configured in relevanssi in some way?

    1. Shea, Relevanssi Premium can fetch user profiles. The posts can be searched for if they appear as posts in the wp_posts database, but otherwise, it’s not possible.

  22. We are using Relevanssi for searching a mix of English and Chinese characters and there are some challenges specific to Chinese we are trying to solve. We would like to index every single substring of a term (so “term” would index as t, te, ter, term, erm, rm, m, er, e, r). Very crazy for English, but very useful for Chinese. We have already set the min word length to 1 (and added every single English char to the stop list to avoid craziness there).

    Relevanssi by default does not do the single characters at the ends of words and also does not index the middles. I see the fuzzy query gets you the inside (still trying to figure out how to implement it) but does it get you the single characters as well? Is there a better way to go about this?


    1. Chris, Relevanssi just doesn’t work very well with Chinese. My recommendation would be to get a search engine that actually works in Chinese. I’m not aware of any, but I guess there must be some.

      You can do the substring indexing, and you can do it only for Chinese text. I don’t think you should do it with English text, because that will lead to a huge amount of garbage results. You should probably come up with a filtering function that goes through your post content (using the relevanssi_post_content filter hook and other necessary similar fields), finds all the Chinese words and then splits them up in substrings and adds those to the post content.

      Once you do that and also enable one-letter searching (do note that setting the minimum word length to 1 is not enough, you also need to unblock the one-letter searches with this: add_filter( 'relevanssi_block_one_letter_searches', '__return_false' );, otherwise one-letter searches will not work), I don’t think you need to adjust the fuzzy matching. Just set Relevanssi to always do partial matching, and you should be reasonably fine.

  23. Hi Mikko
    First of all I would like to thank you for your plugin. It’s really helpful.
    I just have a concern regarding the searching logic, I see that the logic considers the weight based on the tf value calculated which reflects the number of times the word is mentioned in a post. This approach could cause some confusion when a sentence containing a keyword present in most of the articles as the weight will give priority to the posts containing this specific keyword more than other posts containing the whole sentence but the keywords are not repeated. For my case, I preferred to adjust the weight through the words mentioned rarely by dividing the weight by the $matches->count and the tf value to focus on the posts containing more words of the searched sentence.

    I did workaround on that through this function:

    function adjust_match_weights($match, $idf, $term ) {
    global $wpdb;
    $term_count = $wpdb->get_var(“SELECT COUNT(term) from wp_ecrs_relevanssi WHERE term = ‘$term'”);
    $match->weight = $match->weight / ($term_count * $match->tf);
    return $match;
    add_filter(‘relevanssi_match’,’adjust_match_weights’, 10, 3);

    It’s working fine. However I needed to add a separate query for each term through the loop to get the $matches->count value as the hook relevanssi_match doesn’t included. I don’t think this is the best practice due to increasing the database queries when $matches->count was already accessed before. It can even be used if I updated the core but not through accessing the relevanssi_match filter. Could the $matches object be included in the apply_filters function in a next update?

    Also regarding the synonyms, I noticed that if I added a synonym key and value it’s stored in the options table. However, if I came afterwards and wrote another synonym key and value it will overwrite the previous value in the database. I think that a simple concatenation function can solve this issue in the interface.php file.

    Is there a concern changing this line:
    $value = str_replace( $linefeeds, ‘;’, $_REQUEST[‘relevanssi_synonyms’] );

    To be that way?
    $value = get_options(‘relevanssi_synonyms’). “;”. str_replace( $linefeeds, ‘;’, $_REQUEST[‘relevanssi_synonyms’] );

    I tried it and it worked, however there are no filters here which means that I need to update it in the core. If I did so, I will need to change it every time I update the plugin. Couldn’t this be incorporated in a next update?


    1. Mohamed, I’m not really catching the reasoning behind your weighting suggestion. The TF × IDF weighting has been an industry standard for 60 years and for a good reason; it generally works really well. If you want to make a post with a smaller weight for a particular keyword rank higher for that keyword, the easiest solution would be just to pin it using the pinning feature in Relevanssi Premium: that will guarantee first ranking in the search, without any additional code.

      Your filter function is indeed not good for the performance: running all those extra queries will hurt the performance a lot. Why not use IDF instead? It’s already passed as the parameter to the filter, and while it’s not exactly the same as the term count you’re calculating, I think it’s generally the more useful number. Looking at the IDF is more helpful than the raw TF across the whole database, because the raw TF has no upper bound, while IDF has (the number of documents).

      Passing the $matches array as a parameter to the filter doesn’t help, because there’s no $matches->count value in it – Relevanssi doesn’t calculate the raw TF.

      Your suggested fix for the synonym interface would break it badly. Your change would make it impossible to ever remove synonyms, and the same synonyms would be duplicated many times every time the synonyms are saved. There’s no need to fetch the option value, because $_REQUEST[‘relevanssi_synonyms’] already includes all the synonyms, both old and new. If it doesn’t on your site, then there’s something wrong with the way your site works. It’s working as it is.

      1. Well, I am not really aware of the exact search logic used but I have been testing it on many queries I had in my database and I had a problem with the indexing. When I added the filter the indexing worked as it should be.

        Maybe my case needs a special requirement as people usually search by a statement not by a specific word, but I see this as the applicable case for me. That’s why I was asking to add the matches array to the apply filters function rather than updating it in the core plugin for each update or adding unnecessary queries.

        Regarding the synonym option, the logic already overwrites the value in the wp_options table, this is related to the plugin as no one else uses the relevanssi synonyms option, I am not sure how it could be related to my site. I have already tested it and there is no duplication as the new value including the old synonyms +new synonyms overrwrites the old value containing the old synonyms only. If the user wants to delete any of the old synonyms he already has the old synonyms in the input in the synonymes tab on his admin dashboard, he can control it the way he likes rather than doing a mistake adding new synonyms without realising that it overwrites the old synonyms.

        1. It could be that way in the synonyms tab:
          <textarea name='relevanssi_synonyms' id='relevanssi_synonyms' rows='9' cols='60' value="”>

          This will avoid overwriting and duplication of old values .

      2. As I said, may be I am talking with a different approach as my site contains around 2500 posts and people usually search with statements or sentences and I shall need to add synonymes from time to time as per the analysis of user experience (they usually don’t search the exact words so I need to add synonyms based on their input).

        I got your point regarding the duplication but this at least could be shown as an input value in the admin dashboard with the old values and sending the old and new values to the database.

        1. Adding the $matches object to the filter doesn’t help, because the data you need is not in the $matches object.

          I really don’t understand what you’re saying about the synonyms: you are describing the synonym system exactly the way it now works and your suggested change would not work correctly. If it works for you that way, fine, but I can’t change it, because the current code works the way the options are expected to work and your suggestion will make it impossible to ever remove synonyms. I’m not going to break that functionality.

          1. I will check the issue regarding the $matches array when I have access to test tit.
            Regarding the synonyms, I agree with you that adding it in the request function I posted above will cause duplication. To avoid overwriting the old synonyms, the text area could be modified that way in the synonyms-tab.php file:

            This will avoid both overwriting and duplication of old values .

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.