С большой помощью от @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?
Связанный ответ - это правильный способ сделать это.
Создание инструкции 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();