Надеюсь, вам всем хорошего дня и крепкого здоровья
Примечание: я я плохо разбираюсь в SQL
Извините за плохой английский, но я постараюсь объяснить свою проблему
Я использую Laravel v8.x для своего приложения, и после настройки отношений модели, событий, очередей и т. д. теперь я работаю над SQL
Банкомат, у меня 2 модели,
Код: Выделить всё
UserКод: Выделить всё
Post
- имеет много сообщений
Код: Выделить всё
User - принадлежит пользователюToMany (Блокировать)
Код: Выделить всё
User - принадлежит пользователю ToMany (подписаться)
Код: Выделить всё
User - принадлежит пользователю
Код: Выделить всё
Post
5 записей для пользователя
2 записи для Заблокировать
3 записи для сообщения
Таблица: (с использованием фейкера)
< р>
Код: Выделить всё
usersКод: Выделить всё
[
{ id: 1, name: 'Jonathan Beatrice', username: 'kiana.fay', ... },
{ id: 2, name: 'Lacey Kirlin', username: 'kenna.turner', ... },
{ id: 3, name: 'Alexander Schiller', username: 'cassandra95', ... },
{ id: 4, name: 'Daniel Wickozky', username: 'nkoepp', ... },
{ id: 5, name: 'Maymie Lehner', username: 'frami.felton', ... }
]
Код: Выделить всё
blockКод: Выделить всё
[
{ id: 1, by_id: 1, to_id: 2 }, // User #1 block user #2
{ id: 2, by_id: 4, to_id: 1 } // User #4 block user #1
]
Код: Выделить всё
postsКод: Выделить всё
[
{ id: 1, user_id: 2, body: 'Test post', ... },
{ id: 2, user_id: 5, body: 'Lorem ipsum dolor sit amet ...', ... },
{ id: 3, user_id: 4, body: 'ABCD festival soon! ...', ... },
]
Теперь, когда я хочу реализовать систему поиска, у меня возникла проблема, поскольку Я не очень хорош с SQL
Вот мой код
Код: Выделить всё
SearchController.phpКод: Выделить всё
use ...;
use ...;
...
public function posts(Request $request)
{
// For testing purpose
$user = User::with(['userBlocks', 'blocksUser'])->find(1);
// Get all id of user that $user block
// return [2]
$user_blocks = $user->userBlocks->pluck('pivot')->pluck('to_id')->toArray();
// Get all id of user that block $user
// return [4]
$blocks_user = $user->blocksUser->pluck('pivot')->pluck('by_id')->toArray();
// Merge all ids above (must be unique())
// return [2, 4]
$blocks = array_merge($user_blocks, $blocks_user);
// .../search?q=xxx
$query = $request->query('q');
$sql = Post::query();
// Search for posts that has `posts`.`body` LIKE ? ($query)
$sql->where('body', 'LIKE', "%$query%");
// This is where I got confused
$sql->orWhereHas('user', function ($post_user) use ($blocks, $query) {
$post_user
->whereNotIn('id', $blocks) // Exclude posts that has user and their id not in (x, x, x, x, ... ; $block variable above)
->where('name', 'LIKE', "%$query%") // Find user that has name LIKE ? ($query)
->orWhere('username', 'LIKE', "%$query%"); // or Find user that has username LIKE ? ($query)
});
$sql->orderBy('created_at', 'DESC');
$sql->with(['user']);
$posts = $sql->simplePaginate(10, ['*'], 'p');
return $posts;
}
Примечание:< /p>
- Все пользователи имеют в именах алфавит E
- А также все сообщения
- А также все сообщения code> содержит алфавит E
Мы (как Пользователь №1) блокируем Пользователя №2, а Пользователь №4 блокируем нас (Пользователь №1)
Это запрос, когда я использую DB::enableQueryLog() и DB::getQueryLog()
Код: Выделить всё
SELECT
*
FROM
`posts`
WHERE `body` LIKE ?
AND EXISTS
(SELECT
*
FROM
`users`
WHERE `posts`.`user_id` = `users`.`id`
AND (
`id` NOT IN (?)
AND `username` LIKE ?
OR `name` LIKE ?
))
ORDER BY `created_at` ASC
LIMIT 11 OFFSET 0
Заранее спасибо
Если есть какие-либо неясное объяснение, я отредактирую его как можно скорее
Подробнее здесь: https://stackoverflow.com/questions/678 ... wherenotin