mirror of
https://github.com/flarum/framework.git
synced 2025-02-26 06:54:10 +08:00
feat: prioritize title score in fulltext search
Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>
This commit is contained in:
parent
79a9b23096
commit
7ddc8a60dd
@ -88,7 +88,8 @@
|
|||||||
"wikimedia/less.php": "^3.2"
|
"wikimedia/less.php": "^3.2"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"flarum/testing": "^1.0.0"
|
"flarum/testing": "^1.0.0",
|
||||||
|
"symfony/var-dumper": "^6.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
@ -30,8 +30,9 @@ class FulltextGambit implements GambitInterface
|
|||||||
$query = $search->getQuery();
|
$query = $search->getQuery();
|
||||||
$grammar = $query->getGrammar();
|
$grammar = $query->getGrammar();
|
||||||
|
|
||||||
|
// We give discussion title search score a higher weight than post.
|
||||||
$discussionSubquery = Discussion::select('id')
|
$discussionSubquery = Discussion::select('id')
|
||||||
->selectRaw('NULL as score')
|
->selectRaw('MATCH('.$grammar->wrap('discussions.title').') AGAINST (?)*1.5 as score', [$bit])
|
||||||
->selectRaw('first_post_id as most_relevant_post_id')
|
->selectRaw('first_post_id as most_relevant_post_id')
|
||||||
->whereRaw('MATCH('.$grammar->wrap('discussions.title').') AGAINST (? IN BOOLEAN MODE)', [$bit]);
|
->whereRaw('MATCH('.$grammar->wrap('discussions.title').') AGAINST (? IN BOOLEAN MODE)', [$bit]);
|
||||||
|
|
||||||
@ -61,8 +62,7 @@ class FulltextGambit implements GambitInterface
|
|||||||
->groupBy('discussions.id')
|
->groupBy('discussions.id')
|
||||||
->addBinding($subquery->getBindings(), 'join');
|
->addBinding($subquery->getBindings(), 'join');
|
||||||
|
|
||||||
$search->setDefaultSort(function ($query) use ($grammar, $bit) {
|
$search->setDefaultSort(function ($query) {
|
||||||
$query->orderByRaw('MATCH('.$grammar->wrap('discussions.title').') AGAINST (?) desc', [$bit]);
|
|
||||||
$query->orderBy('posts_ft.score', 'desc');
|
$query->orderBy('posts_ft.score', 'desc');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -36,17 +36,19 @@ class ListWithFulltextSearchTest extends TestCase
|
|||||||
['id' => 3, 'title' => 'not in title either', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
['id' => 3, 'title' => 'not in title either', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
||||||
['id' => 4, 'title' => 'not in title or text', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
['id' => 4, 'title' => 'not in title or text', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
||||||
['id' => 5, 'title' => 'తెలుగు', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
['id' => 5, 'title' => 'తెలుగు', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
||||||
['id' => 6, 'title' => '支持中文吗', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
['id' => 6, 'title' => '支持中文吗 acme', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
||||||
|
['id' => 7, 'title' => 'add "acme for life" module!', 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'comment_count' => 1],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->database()->table('posts')->insert([
|
$this->database()->table('posts')->insert([
|
||||||
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>not in text</p></t>'],
|
['id' => 1, 'discussion_id' => 1, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>not in text</p></t>'],
|
||||||
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>lightsail in text</p></t>'],
|
['id' => 2, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>lightsail in text</p></t>'],
|
||||||
['id' => 3, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>another lightsail for discussion 2!</p></t>'],
|
['id' => 3, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>another lightsail for discussion 2! acme for life</p></t>'],
|
||||||
['id' => 4, 'discussion_id' => 3, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>just one lightsail for discussion 3.</p></t>'],
|
['id' => 4, 'discussion_id' => 3, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>just one lightsail for discussion 3.</p></t>'],
|
||||||
['id' => 5, 'discussion_id' => 4, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>not in title or text</p></t>'],
|
['id' => 5, 'discussion_id' => 4, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>not in title or text (acme)</p></t>'],
|
||||||
['id' => 6, 'discussion_id' => 4, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>తెలుగు</p></t>'],
|
['id' => 6, 'discussion_id' => 4, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>తెలుగు</p></t>'],
|
||||||
['id' => 7, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>支持中文吗</p></t>'],
|
['id' => 7, 'discussion_id' => 2, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>支持中文吗</p></t>'],
|
||||||
|
['id' => 8, 'discussion_id' => 5, 'created_at' => Carbon::now()->toDateTimeString(), 'user_id' => 1, 'type' => 'comment', 'content' => '<t><p>some lorem ipsum acme dolor sit amet life kor for</p></t>'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// We need to call these again, since we rolled back the transaction started by `::app()`.
|
// We need to call these again, since we rolled back the transaction started by `::app()`.
|
||||||
@ -87,6 +89,27 @@ class ListWithFulltextSearchTest extends TestCase
|
|||||||
$this->assertEqualsCanonicalizing(['2', '1', '3'], $ids, 'IDs do not match');
|
$this->assertEqualsCanonicalizing(['2', '1', '3'], $ids, 'IDs do not match');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function search_prioritizes_title_search_score_over_post()
|
||||||
|
{
|
||||||
|
$response = $this->send(
|
||||||
|
$this->request('GET', '/api/discussions')
|
||||||
|
->withQueryParams([
|
||||||
|
'filter' => ['q' => 'acme for life'],
|
||||||
|
'include' => 'mostRelevantPost',
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$data = json_decode($response->getBody()->getContents(), true);
|
||||||
|
$ids = array_map(function ($row) {
|
||||||
|
return $row['id'];
|
||||||
|
}, $data['data']);
|
||||||
|
|
||||||
|
$this->assertEquals(['7', '2', '5', '6', '4'], $ids, 'IDs do not match');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user