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)")); }
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"]; }