Drupal запрос отсортирован по появлению ключевых слов в соответствующем результате

0

С большой помощью от @Fky и особенно @Syscall мне удалось изменить запрос drupal для поиска в 3 таблицах вместо двух и добавить условия, а также расщепление ключевых слов и удаление пробелов.

drupal sql условные предложения для нескольких таблиц?

Я хотел бы, чтобы результаты 1) упорядочивались по ключевым словам, появлялись результаты сопоставления, а затем 2) сортировались по заголовку в ASC.

То есть. поиск "бананового яблочного апельсина" для возвращения:

  • банановый апельсин
  • яблоко
  • банан
  • оранжевый

Мне удалось заказать по названию, но не могу понять, как сначала сортировать по ключевым словам?

$term = strip_tags(drupal_substr($_POST['keyword'], 0, 100));
$terms = explode(' ', $term); // split using ' '
$terms = array_map('trim', $terms); // remove unwanted spaces
$termsfiltered = array_filter($terms);
 $or = db_or();
  foreach ($termsfiltered as $term) {
    $or->condition('fd.field_detailed_question_value', '%'.db_like($term).'%', 'LIKE');
    $or->condition('fb.body_value','%'.db_like($term).'%' , 'LIKE');
    $or->condition('n.title','%'.db_like($term).'%' , 'LIKE');
    }
 $query = db_select('node', 'n');

$query->fields('n');
$query->range(0,20); //LIMIT to 15 records
$query->orderBy('title', 'ASC'); //ORDER BY title
$query->leftJoin('field_data_body' , 'fb', 'fb.entity_id=n.nid');
$query->leftJoin('field_data_field_detailed_question' ,'fd', 'fd.entity_id=n.nid');
$query->condition($or);
$query->condition('n.status','1');
$stmt = $query->execute(); // execute the query (returns the "statement" to fetch).

Я нашел один вопрос Сортировка результата sql по наличию набора ключевых слов, который упоминает

Возьмите предложение where, замените все или на +, и убедитесь, что каждый человек, такой как оператор, завернут в скобки, а затем закажите его.

Я также видел пример использования $query-> addExpression...

Будет ли это правильным подходом/как это сделать с запросом drupal? Помогите, пожалуйста :)

Обновление: Или как-то комбинировать orderby с COUNT?

Теги:
drupal
drupal-7

1 ответ

1
Лучший ответ

Связанный ответ - это правильный способ сделать это.

Создание инструкции ORDER BY для запроса Drupal может быть выполнено следующим образом:

$term = strip_tags(drupal_substr($_POST['keyword'], 0, 100));
$terms = explode(' ', $term); // split using ' '
$terms = array_map('trim', $terms); // remove unwanted spaces
$termsfiltered = array_filter($terms);

$order_array = [] ; // Create an empty array to create the string
$or = db_or() ;
foreach ($termsfiltered as $term) {

    // Or condition
    $or->condition('fd.field_detailed_question_value', '%'.db_like($term).'%', 'LIKE');
    $or->condition('fb.body_value','%'.db_like($term).'%' , 'LIKE');
    $or->condition('n.title','%'.db_like($term).'%' , 'LIKE');

    // Order by array (add the concat of each fields)
    $order_array[] = '(concat(title, fd.field_detailed_question_value, fb.body_value) like \'%'.db_like($term).'%\')';
}

$query = db_select('node', 'n');
$query->fields('n');
$query->range(0,20);
$query->orderBy(implode('+',$order_array), 'desc'); // Dynamic order by
$query->leftJoin('field_data_body' , 'fb', 'fb.entity_id=n.nid');
$query->leftJoin('field_data_field_detailed_question' ,'fd', 'fd.entity_id=n.nid');
$query->condition($or);
$query->condition('n.status','1');
$stmt = $query->execute(); // execute the query (returns the "statement" to fetch).

Добавления:

  • $order_array = [] ; перед циклом
  • $order_array[] = '(concat...) внутри цикла
  • $query->orderBy(implode('+',$order_array), 'desc'); изменено

Обратите внимание, что вы можете предотвратить ошибки, используя (или что-то в этом роде):

if (empty($termsfiltered)) { return "No matches."; }

Еще одна вещь. Использование $_POST не является хорошей практикой в Drupal. Если вы пришли из формы, вы должны использовать $form_state['values']['keyword'] вместо $_POST['keyword']: см. Этот пример.


редактировать

$term = strip_tags(drupal_substr($_POST['keyword'], 0, 100));
$terms = explode(' ', $term); // split using ' '
$terms = array_map('trim', $terms); // remove unwanted spaces
$termsfiltered = array_filter($terms);

$order_array = ['title'=>[],'question'=>[],'body'=>[]] ; // Create an empty array to create the string
$or = db_or() ;
foreach ($termsfiltered as $term) {

    // Or condition
    $or->condition('fd.field_detailed_question_value', '%'.db_like($term).'%', 'LIKE');
    $or->condition('fb.body_value','%'.db_like($term).'%' , 'LIKE');
    $or->condition('n.title','%'.db_like($term).'%' , 'LIKE');

    // Order by array (add the concat of each fields)
    $order_array['title'][] = '(title like \'%'.db_like($term).'%\')';
    $order_array['question'][] = '(fd.field_detailed_question_value like \'%'.db_like($term).'%\')';
    $order_array['body'][] = '(fb.body_value like \'%'.db_like($term).'%\')';
}

$query = db_select('node', 'n');
$query->fields('n');
$query->range(0,20);
$query->orderBy(implode('+',$order_array['title']), 'desc'); // Dynamic order by
$query->orderBy(implode('+',$order_array['question']), 'desc'); // Dynamic order by
$query->orderBy(implode('+',$order_array['body']), 'desc'); // Dynamic order by
$query->leftJoin('field_data_body' , 'fb', 'fb.entity_id=n.nid');
$query->leftJoin('field_data_field_detailed_question' ,'fd', 'fd.entity_id=n.nid');
$query->condition($or);
$query->condition('n.status','1');
$stmt = $query->execute();
  • 0
    Благодаря Syscall, результаты поиска, к сожалению, пока не содержат первых строк, в которых было найдено несколько ключевых слов. Например, первые два результата не содержат одно из ключевых слов.
  • 1
    @ Маркус Извините, я чего-то не понимаю. Как не может содержать одно из ключевых слов, потому что есть условие для фильтрации результата? Вы имеете в виду, что отображаете только заголовок и хотите показать большинство совпадений в заголовке?
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню