MySQL全文搜索修改,以任何顺序搜索单词

时间:2018-07-05 18:35:05

标签: php mysql sql full-text-search sql-like

我正在将wpDataTables用于家谱网站,到目前为止,该网站的运行非常出色。唯一的障碍是我的搜索过滤器不会在给定的搜索中返回该过滤器中的所有单词。例如,字符串Karl Friedrich Wilhelm将完全返回该字符串。我想更改编码以允许使用不同的单词顺序(例如Friedrich Karl Wilhelm等),当单词之间用空格分隔时,可以从该表列中以任何顺序从数据库中检索它们,但不能从整个表中检索它们

当前,我可以使用%和_通配符进行搜索而不会出现问题。我读了一些有关全文搜索的文章,该文章可能有用,但前提是可以保留我对通配符的使用,并使其在不破坏代码的情况下可以与我的所有列一起使用。 (我所有的SQL条目都是TEXT或VARCHAR格式。)我不确定在这种情况下全文搜索是否会更好,或者“ like”语句是否会更有效(我也读过这可能向我开放injection attacks)。我找到了article that might be of use,但我不知道如何实现。

代码分为两部分:第一部分是全局搜索。恐怕如果我更改它以进行全文搜索,可能会使查询花费更长的时间,因为它将搜索整个表而不是单个列。第二个是每个单独的过滤器,在我的网站上它适用于“姓名”,“出生地”等。

我需要对以下代码进行什么更改,以使过滤器以任意顺序返回结果?您可以在http://mypomerania.com/person-search/上的网站上看到一个示例,该示例当前如何在MySQL和PHP上同时使用PHP,并且我还无法弄清楚如何实现我在其他文章中所读到的内容。任何指导将不胜感激。谢谢!

            // 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);
            }

        }

    }

0 个答案:

没有答案