PHP通过省略单词将搜索字符串更改为较小的相关性

时间:2018-08-15 11:40:29

标签: php full-text-search

这是我第一次在这里问问题,所以如果我没有100%正确地做所有事情,请不要钉死我。

我正在尝试使用php和mysql创建全文搜索,以返回因相关性而降低的结果。 用户将输入要在文章中查找的单词,因此我不知道他将使用多少个单词。 假设用户在类似

的文章中寻找不同的职业

$ searchstring ='画家瓦工贝克教皇'

现在,我首先要搜索出现所有这些单词的文本。 在下一步中,我想通过保留一个单词来扩大搜索范围。

第二个搜索字符串应仅为

'画家瓦工贝克'

第三名:

画家瓦工教皇

第四次:

画家贝克教皇

第五名:

瓦工画家教皇

然后所有这些新变体都应该再次发生相同的情况,例如第二个结果:

画家瓦工

画家贝克

瓦工面包师

然后针对此变体一次又一次,直到只剩下一个字为止。

这是到目前为止的内容,但这会导致死胡同,因为我无法将所有子结果存储在单独的数组中,并且一次又一次地对它们执行相同的操作。但是我想我的方法还是完全错误的,对此我可能无法找到一个合适的解决方案。 那么,有人可以将我推向正确的方向吗?

`
';

            $stringarray = explode( ' ', $searchstring );   
            $collectionArray = array();
            $newString = '';
            $run = count($stringarray);
            while ($run > 1) {
            $length = count($stringarray);
            $counter = $length-1;

            echo '<br><br>';
            echo '$counter: ' . $counter . '<br>';
            while ($counter > 0) {
            for ($i = $length-1; $i >=0; $i--) 
            {
                echo 'Counter: ' . $counter . ' | Index ' . $i .': ';
                if ($i == ($counter)) {
                echo '-----<br>';   
                 continue;  
                } 
            echo $stringarray[$i] . '<br>';
            $newString = $newString . ' ' . $stringarray[$i];

            //echo $counter . ' danach';
            }
            //print_r($collectionArray);
            $collectionArray[] = $newString;
            $counter--;
            $newString = '';
            echo '<br><br>';
            }
            array_pop($stringarray);
            print_r($stringarray);
            echo '<br>';
            print_r($collectionArray);
            $run--;
            }

?>`

1 个答案:

答案 0 :(得分:0)

一种解决方案是将其构建为递归函数(调用自身的函数)。您从每个单词开始,调用函数本身以添加其他单词。如果您提供结果数组作为参考,则可以避免沿着已经完成的路径前进:

$words = explode(' ', 'painter bricklayer baker pope');

function compileSearchStrings(array &$searchStrings,  array $available, array $used = []) {
  // foreach way to go
  foreach($available as $word) {
    $words = $used;
    $words[] = $word;
    sort($words);
    $searchString = implode(' ', $words);
    // did we walk down that path already?
    if (!in_array($searchString, $searchStrings, TRUE)) {
      // store path
      $searchStrings[] = $searchString;
      // still a way to go?
      if (count($available) > 0) {
        compileSearchStrings($searchStrings, array_diff($available, array($word)), $words);
      }
    }
  } 
}

$seachStrings = [];
compileSearchStrings($seachStrings, $words);
var_dump($seachStrings);

如果可以在没有参考的情况下实现它,但是这将生成需要删除的重复项:

function compileSearchStringsNoRef(array $available, array $used = []) {
  $result = [];
  foreach($available as $word) {
    $words = $used;
    $words[] = $word;
    sort($words);
    $result[] = implode(' ', $words);
    if (count($available) > 0) {
      array_push(
        $result,
        ...compileSearchStringsNoRef(array_diff($available, array($word)), $words)
      );
    }
  } 
  // remove duplicates and return
  return array_unique($result);
}
var_dump(compileSearchStringsNoRef($words));

要首先获取更具体的查询,可以按长度对数组进行排序:

function sortByLength($array) {
    usort(
        $array,
        function($a, $b) {
            $aLength = strlen($a);
            $bLength = strlen($b);
            if ($aLength === $bLength) {
                return strnatcasecmp($a, $b);
            } 
            return $bLength - $aLength;
        }
    );
    return $array;
}
var_dump(sortByLength(compileSearchStringsNoRef($words)));