0

I have an entity query where I search the body for user provided text. I'm performing the query like so

$searchterm = 'test';
    $query = \Drupal::entityQuery('node')
            ->condition('status', NODE_PUBLISHED)
            ->condition('body', $searchterm, 'CONTAINS');

This gives me the results I need, but what if I run into a situation where the body contains the text 'test-1' but I want searches for 'test1' to bring up that result.

Is there anyway that I can write a query that ignores all special characters in the field I'm searching?

  • 3
    No, the API doesn't support that. This is also not performant at all. Look at search api if you want to have a performant search with features like that – Berdir Feb 28 '17 at 21:29
3

Drupal does not supply a solution to your problem out of the box. However you can create a list of all the permutations and create a condition for each of them.


Code snippet

$searchterm = 'test-1_2 3';

$query = \Drupal::entityQuery('node')
  ->condition('status', NODE_PUBLISHED);

// permutation generator function.
$permutations = function($source_term) {
  $result = [$source_term];
  $unprocessed_terms = [$source_term];
  $regex = '/[\W_]/'; // Selects all the non-alphanumeric characters and _

  while (!empty($unprocessed_terms)) {
    $unprocessed_term = array_pop($unprocessed_terms);
    $matches = [[]];

    // By using PREG_OFFSET_CAPTURE we get the position of the match.
    preg_match_all($regex, $unprocessed_term, $matches, PREG_OFFSET_CAPTURE);
    foreach($matches[0] as list($match, $pos)) {
      $result[] = $unprocessed_terms[] = substr_replace($unprocessed_term, '', $pos, 1);
    }
  }

  // the above algorithm will create duplicates.
  return array_unique($result);
};

// Create an OR condition group that contains a 
// condition for each permutation term.
$query->condition($or = $query->orConditionGroup());
foreach ($permutations($searchterm) as $term) {
  $or->condition('body', $term, 'CONTAINS');
}

$nids = $query->execute();
  • P.S. performance of the above code can be improved greatly with caches. – Eyal Apr 4 '17 at 10:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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