Пользователь может отправить форму поиска с вводом, таким как dog cat +bird
. Ожидается, что он вернет все сообщения с заголовком, содержащим (dog
ИЛИ cat
) И bird
.
Я считаю, что мне нужно добавить dog
и cat
в подзапрос, такой как:
protected function orLike(string $column, string $value): Builder
{
return $this->builder
->where(function (Builder $subQuery) use ($column, $value) {
$subQuery->orWhere($column, 'like', '%'.$value.'%'); // dog
//$subQuery->orWhere($column, 'like', '%'.$value.'%'); // cat
//$subQuery->orWhere($column, 'like', '%'.$value.'%'); etc...
});
}
выше orLike
- моя функция в al oop, которая выполняется для каждого проанализированный необязательный поисковый термин (dog
, cat
)
Как мне сделать так, чтобы каждый необязательный термин (dog
или cat
) ПРИЛОЖЕН к $subquery
с orWhere()
для каждый термин?
Прямо сейчас, очевидно, он запускает новый where()
с одним подзапросом для каждого термина.
Не уверен, что я достаточно ясен. По сути, я пытаюсь создать довольно простой поисковый ввод, в котором пользователи могут ввести +bird -cat dog duck
, что означает bird
ДОЛЖНО быть в заголовке И cat
НЕ ДОЛЖНО быть в заголовке И (содержит dog
ИЛИ duck
)
edit: дополнительная информация по запросу в комментариях
/*
usage: return $this->parseLike('title', '+dog cat -bird elephant duck');
*/
protected function parseLike(string $column, string $value)
{
// [...] irrelevant code
/*
$terms is a collection of terms, such as:
+dog
cat
-bird
elephant
duck
*/
return $terms
->unique()
->map(function (string $term) {
switch (\substr($term, 0, 1)) {
case '+':
return ['like' => \substr($term, 1)]; // function "like()" is called for terms with operator "+" such as "+dog"
case '-':
return ['notLike' => \substr($term, 1)]; // function "notLike()" is called for terms with operator "-" such as "-bird"
default:
return ['orLike' => $term]; // function "orLike()" is called for terms with no operator, such as "elephant" or "duck" or "cat"
}
})
->each(function ($combination) use ($column) {
collect($combination)
->reject(function ($term) {
return empty($term);
})
->each(function (string $term, string $operator) use ($column) {
return $this->{$operator}($column, $term);
});
});
}