Drupal 8, Search API SOLR.

I'd like to not return nodes if there are any matches between a field of negative keywords (on the node) and the query string the user has entered.

Module search_api_solr currently set up with several fields, matching in node titles, body and keyword fields.

e.g. node titled "I can't find my elephant" with a negative keyword field containing "wallet" to not show up in a search "I can't find my wallet".

3 Answers 3


You don't need to do this in solr, you can do it in the query or with views filters.

Something like this:

$solrIndex = \Drupal::entityTypeManager()->getStorage('search_api_index')->load('global');
$query = $solrIndex->query();
$query->addCondition('title', $search_string);

$search_terms = explode(' ', $search_string);

// Don't match items where elements in the title match the stop words
// for an entity.
foreach ($search_terms as $term) {
  $query->addCondition('field_stop_words', $term, '<>');

Please check the following screenshots.

enter image description here

enter image description here

  • I'm hoping to exclude the nodes based on negative keywords on each node.
    – TCLopez
    Commented May 26, 2017 at 12:18

This is the solution I came to:

Add the field in search API

Add a filter query in hook_search_api_solr_query_alter to exclude nodes with the negative keywords.

    // Generate a filter query to do a negative search for each word in the search string.
    $search_words = explode(' ', trim($query_string));
    $filter_query_parts = [];
    for ($x = 1; $x <= count($search_words); $x++) {
        $filter_query_parts[] = '-ts_field_negative_keywords:%' . $x . '%';

    $filter_query_text = '( ' . implode(" OR ", $filter_query_parts) . ')';

    // Apply the filter query to the search.
    $solrQuery->createFilterQuery('ts_field_negative_keywords')->setQuery($filter_query_text, $search_words);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.