コード例 #1
0
ファイル: ExpressionTest.php プロジェクト: teamtnt/tntsearch
 public function testToPostfix()
 {
     $exp = new Expression();
     $this->assertEquals(['a', 'b', '&', 'c', '|'], $exp->toPostfix("a&b|c"));
     $this->assertEquals(['aw', 'bw', '&', 'cw', '|'], $exp->toPostfix("aw&bw|cw"));
     $this->assertEquals(['a', 'b', 'd', 'c', '&', '|', '&'], $exp->toPostfix("a&(b|d&c)"));
     $this->assertEquals(['a', 'b', '|'], $exp->toPostfix("a|b"));
     $this->assertEquals(['great', 'awsome', '|'], $exp->toPostfix("great|awsome"));
     $this->assertEquals(['great', 'awsome', '|'], $exp->toPostfix("great or awsome"));
     $this->assertEquals(['great', 'awsome', '&'], $exp->toPostfix("great awsome"));
     $this->assertEquals(['email', 'test', '&', 'com', '&'], $exp->toPostfix("email test com"));
     $this->assertEquals(['email', 'test', '&', 'com', '&'], $exp->toPostfix("*****@*****.**"));
     $this->assertEquals(['first', 'last', '&', 'something', 'else', '&', '|'], $exp->toPostfix("(first last) or (something else)"));
 }
コード例 #2
0
ファイル: TNTSearch.php プロジェクト: teamtnt/tntsearch
 public function searchBoolean($phrase, $numOfResults = 100)
 {
     $stack = [];
     $startTimer = microtime(true);
     $expression = new Expression();
     $postfix = $expression->toPostfix("|" . $phrase);
     foreach ($postfix as $token) {
         if ($token == '&') {
             $left = array_pop($stack);
             $right = array_pop($stack);
             if (is_string($left)) {
                 $left = $this->getAllDocumentsForKeyword($this->stemmer->stem($left), true)->pluck('doc_id');
             }
             if (is_string($right)) {
                 $right = $this->getAllDocumentsForKeyword($this->stemmer->stem($right), true)->pluck('doc_id');
             }
             if (is_null($left)) {
                 $left = [];
             }
             if (is_null($right)) {
                 $right = [];
             }
             $stack[] = array_values(array_intersect($left, $right));
         } else {
             if ($token == '|') {
                 $left = array_pop($stack);
                 $right = array_pop($stack);
                 if (is_string($left)) {
                     $left = $this->getAllDocumentsForKeyword($this->stemmer->stem($left), true)->pluck('doc_id');
                 }
                 if (is_string($right)) {
                     $right = $this->getAllDocumentsForKeyword($this->stemmer->stem($right), true)->pluck('doc_id');
                 }
                 if (is_null($left)) {
                     $left = [];
                 }
                 if (is_null($right)) {
                     $right = [];
                 }
                 $stack[] = array_unique(array_merge($left, $right));
             } else {
                 if ($token == '~') {
                     $left = array_pop($stack);
                     if (is_string($left)) {
                         $left = $this->getAllDocumentsForWhereKeywordNot($this->stemmer->stem($left), true)->pluck('doc_id');
                     }
                     if (is_null($left)) {
                         $left = [];
                     }
                     $stack[] = $left;
                 } else {
                     $stack[] = $token;
                 }
             }
         }
     }
     if (count($stack)) {
         $docs = new Collection($stack[0]);
     } else {
         $docs = new Collection();
     }
     $counter = 0;
     $docs = $docs->filter(function ($item) use(&$counter, $numOfResults) {
         $counter++;
         if ($counter <= $numOfResults) {
             return $item;
         }
     });
     $stopTimer = microtime(true);
     if ($this->isFileSystemIndex()) {
         return $this->filesystemMapIdsToPaths($docs)->toArray();
     }
     return ['ids' => $docs->toArray(), 'hits' => $docs->count(), 'execution time' => round($stopTimer - $startTimer, 7) * 1000 . " ms"];
 }