MySQL полнотекстовый поиск модификаций, поиск слов в любом порядке - PullRequest
0 голосов
/ 05 июля 2018

Я использую wpDataTables для сайта по генеалогии, который до сих пор работал фантастически. Единственным препятствием является то, что мои поисковые фильтры не возвращают все слова в этом фильтре в данном поиске. Например, строка Карла Фридриха Вильгельма вернет именно это. Я хотел бы изменить кодировку, чтобы учесть различный порядок слов, такой как Фридрих Карл Вильгельм и т. Д., Когда слова разделяются пробелом, их можно извлечь из базы данных в любом порядке в этом столбце таблицы, но не из полной таблицы .

В настоящее время я могу использовать подстановочные знаки% и _ для поиска без проблем. Я прочитал немного о полнотекстовом поиске, который может сработать, но только если можно будет использовать мои символы подстановки и заставить его работать со всеми моими столбцами, не нарушая код. (Все мои записи SQL представлены в формате TEXT или VARCHAR.) Я не уверен, что полнотекстовый поиск будет лучше в этом случае, или если выражение «как» будет более эффективным (я также читал, что это может открыть мне до инъекционных атак) Я нашел статью , которая могла бы быть полезной , но я не знаю, как ее реализовать.

В коде есть две части: первая - для глобального поиска. Боюсь, если я изменю это, чтобы выполнить полнотекстовый поиск, это может сделать запросы значительно дольше, так как это будет искать всю таблицу вместо отдельных столбцов. Второй - это каждый отдельный фильтр, который на моем сайте работает для таких вещей, как «Имя», «Место рождения» и т. Д.

Что мне нужно изменить в приведенном ниже коде, чтобы мои фильтры возвращали результаты в любом порядке? Вы можете увидеть пример того, как он в настоящее время функционирует на моем сайте по адресу http://mypomerania.com/person-search/ Я новичок в использовании PHP с MySQL, и я не смог понять, как реализовать то, что я прочитал в других сообщения. Любое руководство будет оценено. Спасибо!

            // Global search
            $search = '';
            if (!empty($_POST['search']['value'])) {
                $search = " (";
                for ($i = 0; $i < count($aColumns); $i++) {
                    if ($_POST['columns'][$i]['searchable'] == "true") {
                        if (in_array($wdtParameters['data_types'][$_POST['columns'][$i]['name']], array('date', 'datetime', 'time'))) {
                            continue;
                        } else {
                            if (is_null($wdtParameters['foreignKeyRule'][$_POST['columns'][$i]['name']])) {
                                $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . addslashes($_POST['search']['value']) . "%' OR ";
                            } else {
                                $foreignKeyRule = $wdtParameters['foreignKeyRule'][$_POST['columns'][$i]['name']];
                                $joinedTable = WPDataTable::loadWpDataTable($foreignKeyRule->tableId);
                                $distinctValues = $joinedTable->getDistinctValuesForColumns($foreignKeyRule);
                                $distinctValues = array_map('strtolower', $distinctValues);

                                $filteredValues = preg_grep('~' . preg_quote(strtolower($_POST['search']['value']), '~') . '~', $distinctValues);

                                if (!empty($filteredValues)) {
                                    $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` IN (" . implode(', ', array_keys($filteredValues)) . ")  OR ";
                                } else {
                                    $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . addslashes($_POST['search']['value']) . "' OR ";
                                }
                            }

                        }
                    }
                }
                $search = substr_replace($search, "", -3);
                $search .= ')';
            }

            // Individual column filtering
            for ($i = 0; $i < count($aColumns); $i++) {

                $columnSearchFromTable = false;
                $columnSearchFromDefaultValue = false;

                if (isset($_POST['columns'][$i]['search']) &&
                    $_POST['columns'][$i]['search']['value'] != '' &&
                    $_POST['columns'][$i]['search']['value'] != '|') {
                    $columnSearchFromTable = true;
                }
                if (($_POST['draw'] == 1 || $columnSearchFromTable == true) &&
                    (isset($wdtParameters['filterDefaultValue'][$i]) &&
                    $wdtParameters['filterDefaultValue'][$i] !== '' &&
                    $wdtParameters['filterDefaultValue'][$i] !== '|' )) {
                    $columnSearchFromDefaultValue = true;
                }
                if ($_POST['columns'][$i]['searchable'] == true && ($columnSearchFromTable || $columnSearchFromDefaultValue)) {

                    //Apply placeholders when they are set in filter ​predefined value
                    $wdtParameters['filterDefaultValue'][$i]=  WDTTools::applyPlaceholders($wdtParameters['filterDefaultValue'][$i]);

                    $columnSearch = $columnSearchFromTable ? $_POST['columns'][$i]['search'][value] : $wdtParameters['filterDefaultValue'][$i];
                    if (!empty($search)) {
                        $search .= ' AND ';
                    }
                    if (isset($wdtParameters['filterTypes'][$aColumns[$i]])) {
                        switch ($wdtParameters['filterTypes'][$aColumns[$i]]) {
                            case 'number-range':
                                list($left, $right) = explode('|', $columnSearch);
                                if ($left !== '') {
                                    $left = (float)$left;
                                    $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` >= $left ";
                                }
                                if ($right !== '') {
                                    $right = (float)$right;
                                    if (!empty($search) && $left !== '') {
                                        $search .= ' AND ';
                                    }
                                    $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` <= $right ";
                                }
                                break;
                            case 'date-range':
                            case 'time-range':
                            case 'datetime-range':
                                list($left, $right) = explode('|', $columnSearch);
                                $date_format = '';
                                if ($wdtParameters['filterTypes'][$aColumns[$i]] != 'time-range') {
                                    $date_format = str_replace('m', '%m', get_option('wdtDateFormat'));
                                    $date_format = str_replace('M', '%M', $date_format);
                                    $date_format = str_replace('Y', '%Y', $date_format);
                                    $date_format = str_replace('y', '%y', $date_format);
                                    $date_format = str_replace('d', '%d', $date_format);
                                }
                                if ($wdtParameters['filterTypes'][$aColumns[$i]] == 'datetime-range'
                                    || $wdtParameters['filterTypes'][$aColumns[$i]] == 'time-range'
                                ) {
                                    $date_format .= ' ' . get_option('wdtTimeFormat');
                                    $date_format = str_replace('H', '%H', $date_format);
                                    $date_format = str_replace('h', '%h', $date_format);
                                    $date_format = str_replace('i', '%i', $date_format);
                                    $date_format = str_replace('A', '%p', $date_format);
                                }
                                if ($left && $right) {
                                    $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` BETWEEN STR_TO_DATE('$left', '$date_format') AND STR_TO_DATE('$right', '$date_format') ";
                                } elseif ($left) {
                                    $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` >= STR_TO_DATE('$left', '$date_format') ";
                                } elseif ($right) {
                                    $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` <= STR_TO_DATE('$right', '$date_format') ";
                                }
                                break;
                            case 'select':
                                if ($columnSearch == 'possibleValuesAddEmpty') {
                                    $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '' OR `" . $aColumns[$i] . "` IS NULL";
                                } else {
                                    if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
                                        $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . $columnSearch . "' ";
                                    } else {
                                        $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . $columnSearch . "%' ";
                                    }
                                }
                                break;
                            case 'checkbox':
                            case 'multiselect':
                                if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
                                    // Trim regex parts for first and last one
                                    if (strpos($columnSearch, '$') !== false) {
                                        $checkboxSearches = explode('$|^', $columnSearch);
                                        $checkboxSearches[0] = substr($checkboxSearches[0], 1);
                                        if (count($checkboxSearches) > 1) {
                                            $checkboxSearches[count($checkboxSearches) - 1] = substr($checkboxSearches[count($checkboxSearches) - 1], 0, -1);
                                        } else {
                                            $checkboxSearches[0] = substr($checkboxSearches[0], 0, -1);
                                        }
                                    } else {
                                        $checkboxSearches = explode('|', $columnSearch);
                                    }
                                } else {
                                    $checkboxSearches = explode('|', $columnSearch);
                                }
                                $j = 0;
                                $search .= " (";
                                foreach ($checkboxSearches as $checkboxSearch) {
                                    if ($j > 0) {
                                        $search .= " OR ";
                                    }

                                    if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
                                        $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . $checkboxSearch . "' ";
                                    } else {
                                        $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . $checkboxSearch . "%' ";
                                    }

                                    $j++;
                                }
                                $search .= ") ";
                                break;
                            case 'text':
                            case 'number':
                                if (is_null($wdtParameters['foreignKeyRule'][$_POST['columns'][$i]['name']])) {
                                    if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
                                        $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . $columnSearch . "' ";
                                    } else {
                                        if ($wdtParameters['filterTypes'][$aColumns[$i]] == 'number') {
                                            $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '" . $columnSearch . "%' ";
                                        } else {
                                            $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . $columnSearch . "%' ";
                                        }
                                    }
                                } else {
                                    $foreignKeyRule = $wdtParameters['foreignKeyRule'][$_POST['columns'][$i]['name']];
                                    $joinedTable = WPDataTable::loadWpDataTable($foreignKeyRule->tableId);
                                    $distinctValues = $joinedTable->getDistinctValuesForColumns($foreignKeyRule);
                                    $distinctValues = array_map('strtolower', $distinctValues);

                                    if ($wdtParameters['exactFiltering'][$aColumns[$i]] == 1) {
                                        $filteredValues = preg_grep('~^' . preg_quote(strtolower($columnSearch), null) . '$~', $distinctValues);
                                    } else {
                                        $filteredValues = preg_grep('~' . preg_quote(strtolower($columnSearch), '~') . '~', $distinctValues);
                                    }

                                    if (!empty($filteredValues)) {
                                        $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` IN (" . implode(', ', array_keys($filteredValues)) . ")";
                                    } else {
                                        $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` = '" . $columnSearch . "' ";
                                    }
                                }
                                break;
                            default:
                                $search .= '`' . $tableName . '`.`' . $aColumns[$i] . "` LIKE '%" . $columnSearch . "%' ";
                        }
                    }
                }
            }

            if ($search) {
                $search = 'WHERE ' . $search;
                $parsedSearch = $parser->parse($search);
            }

        }

    }
...