upgrade search engine
This commit is contained in:
parent
45bd1b408d
commit
138b4f24ee
|
@ -63,6 +63,12 @@ class PostRepositoryQuery extends RepositoryQuery
|
|||
|
||||
public function search(?string $keywords, ?string $tag)
|
||||
{
|
||||
$keywords = explode(' ', $keywords);
|
||||
|
||||
$filter = fn($keyword) => trim($keyword) !== '' && preg_match('/[a-zA-Z]+/', $keyword) && mb_strlen($keyword) > 3;
|
||||
|
||||
$keywords = array_filter($keywords, $filter);
|
||||
|
||||
if ($keywords) {
|
||||
$conn = $this->repository->getEm()->getConnection();
|
||||
|
||||
|
@ -70,43 +76,91 @@ class PostRepositoryQuery extends RepositoryQuery
|
|||
'SELECT
|
||||
post.id,
|
||||
post.title,
|
||||
MATCH(post.title) AGAINST(:search) AS MATCH_TITLE,
|
||||
MATCH(post.content) AGAINST(:search) AS MATCH_CONTENT
|
||||
post.content,
|
||||
post.published_at
|
||||
FROM post
|
||||
WHERE
|
||||
post.status = 1 AND
|
||||
post.published_at < :date
|
||||
ORDER BY
|
||||
MATCH_TITLE DESC,
|
||||
MATCH_CONTENT DESC
|
||||
');
|
||||
|
||||
$statement = $query->execute([
|
||||
':search' => $keywords,
|
||||
':date' => (new \DateTime())->format('Y-m-d H:i:s'),
|
||||
]);
|
||||
|
||||
$results = $statement->fetchAll();
|
||||
$ids = [];
|
||||
$matches = [];
|
||||
|
||||
foreach ($results as $k => $v) {
|
||||
$rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
|
||||
$added = false;
|
||||
$initWords = explode(' ', $v['title']);
|
||||
$words = [];
|
||||
|
||||
if ($rate >= 7) {
|
||||
$ids[] = $v['id'];
|
||||
foreach ($initWords as $initWord) {
|
||||
$words = array_merge($words, preg_split('/[:_-]+/', $initWord));
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == count($ids)) {
|
||||
foreach ($results as $k => $v) {
|
||||
$rate = ($v['MATCH_TITLE'] * 2) + $v['MATCH_CONTENT'];
|
||||
$words = array_filter($words, $filter);
|
||||
|
||||
if ($rate >= 6) {
|
||||
$ids[] = $v['id'];
|
||||
foreach ($keywords as $keyword) {
|
||||
if ($added) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($words as $word) {
|
||||
if ($added) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_contains(mb_strtolower($word), mb_strtolower($keyword))) {
|
||||
$matches[] = [
|
||||
'id' => $v['id'],
|
||||
'published_at' => $v['published_at'],
|
||||
'similarity' => 100,
|
||||
];
|
||||
|
||||
$added = true;
|
||||
} elseif(str_contains($v['content'], $keyword)) {
|
||||
$matches[] = [
|
||||
'id' => $v['id'],
|
||||
'published_at' => $v['published_at'],
|
||||
'similarity' => 99,
|
||||
];
|
||||
|
||||
$added = true;
|
||||
} else {
|
||||
$lev = levenshtein($word, $keyword);
|
||||
$similarity = 100 - ($lev * 100 / mb_strlen($word));
|
||||
|
||||
if ($similarity > 70) {
|
||||
$matches[] = [
|
||||
'id' => $v['id'],
|
||||
'published_at' => $v['published_at'],
|
||||
'similarity' => $similarity,
|
||||
];
|
||||
|
||||
$added = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usort($matches, function($a, $b) {
|
||||
if ($a['similarity'] > $b['similarity']) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ($b['similarity'] > $a['similarity']) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return ($a['published_at'] <> $b['published_at']) * -1;
|
||||
});
|
||||
|
||||
$ids = array_column($matches, 'id');
|
||||
|
||||
if (!$ids) {
|
||||
$ids = [-1];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue