---
title: "Vyhľadávanie vo viacerých stĺpcoch — Query Builder | Roundly"
description: "Jedno vyhľadávacie pole naprieč stĺpcami cez search() — doslovná fráza, jedno zoskupené OR, bezpečné voči NULL a šetrné k trigramovým indexom PostgreSQL."
url: https://roundly-consulting.com/sk/open-source/navody/query-builder-for-laravel/vyhladavanie
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Query Builder for Laravel](https://roundly-consulting.com/sk/open-source/navody/query-builder-for-laravel.md)

# Vyhľadávanie vo viacerých stĺpcoch

AllowedFilter::search(string $name, array $columns, array $asText = \[\]) dá endpointu jedno vyhľadávacie pole, ktoré prehľadá viac stĺpcov naraz: riadok vyhovie, keď frázu obsahuje ktorýkoľvek z nich. Namiesto interného názvu prijíma zoznam stĺpcov:

```php
use RoundlyConsulting\QueryBuilder\AllowedFilter;

->allowedFilters(
    AllowedFilter::search('search', ['name', 'email']),                              // bare columns: index-friendly
    AllowedFilter::search('q', ['name', 'key', 'kind', 'tags'], asText: ['tags']),   // jsonb compared as text
)

// After a join, qualify the columns:
QueryBuilder::for(User::query()->join('teams', 'teams.id', '=', 'users.team_id')->select('users.*'))
    ->allowedFilters(AllowedFilter::search('search', ['users.name', 'teams.name']));
```

Request sa zostaví do jednej zoskupenej podmienky — na PostgreSQL ILIKE, inde LIKE — pričom vzor aj escape znak sa viažu pre každý stĺpec:

```sql
-- GET /users?filter[search]=ann  (PostgreSQL; like on the other engines)
("name" ilike ? escape ? or "email" ilike ? escape ?)
-- bound once per column: '%ann%' and '\'
```

## Jedna fráza

```php
// ?filter[search]=Smith, John         → one phrase: "Smith, John"
// ?filter[search][]=a&filter[search][]=b → rejoined: "a,b"
// ?filter[search]=,                    → no constraint
// ?filter[search]=not:draft            → searched as the text "not:draft"
// ?filter[search]=ann&filter[status]=published → (name or email contains "ann") and status = 'published'
```

- Vyhľadávacie pole obsahuje jeden kus textu, preto je čiarka jeho súčasťou: Smith, John sa hľadá presne tak, ako bolo zadané, nikdy ako Smith alebo John. Zámerne sa to líši od zoznamu v partial(), ktorý je OR hodnôt.
- Zápis poľom sa spojí späť čiarkami. Fráza sa po spojení skráti na limits.max\_value\_length a potom oreže cez mb\_trim (medzery, tabulátory, nezlomiteľné medzery).
- Prázdna fráza — prázdna, len z bielych znakov alebo len z čiarok — nepridá žiadnu podmienku.
- Prefix operátora sa nečíta (not:draft sa hľadá ako text) a true / false ostávajú textom.

## Doslovne, bezpečne voči NULL a zoskupene

- %, \_ a \\ vo fráze sa escapujú a porovnávajú s explicitnou klauzulou escape '\\' na každom engine, takže sú to obyčajné znaky.
- Stĺpec s hodnotou NULL jednoducho nevyhovie; riadok sa aj tak nájde cez iný stĺpec.
- Stĺpce tvoria jedno OR v zátvorkách, spojené cez AND so všetkými ostatnými filtrami: filter\[search\]=ann&filter\[status\]=published nikdy nevráti koncept, ktorý spomína „ann“.
- Veľkosť písmen rieši engine, rovnako ako pri partial() (pozrite Filtre).

## Netextové stĺpce — asText

Holý stĺpec sa porovnáva tak, ako je — nikdy sa neprevádza na malé písmená ani nepretypuje. Stĺpec uvedený v asText (musí byť aj v $columns) sa pretypuje na text:

| Driver | Stĺpec v asText | Veľkosť písmen |
| --- | --- | --- |
| PostgreSQL | `"tags"::text ilike ?` | Podľa ctype locale databázy, ako pri partial(). |
| MySQL / MariaDB | ``cast(`tags` as char) like ?`` | Podľa collation spojenia (predvolené utf8mb4\_unicode\_ci v Laraveli ignoruje veľkosť písmen aj diakritiku), takže JSON sa správa ako text. |
| SQLite a ostatné | bez zmeny | Len písmená ASCII, ako pri partial(). |

PostgreSQL nemá ILIKE pre stĺpce json / jsonb, uuid, integer, inet ani natívne enumy: nepretypovaný stĺpec skončí chybou SQLSTATE 42883 (operator does not exist). Každý netextový stĺpec preto uveďte v asText. Na MySQL sa nepretypovaný JSON stĺpec porovnáva binárne — rozlišuje veľkosť písmen, takže foo nenájde \["Foo"\] — a aj to asText vyrieši.

## Indexy

Keďže sa stĺpec nikdy neprevádza na malé písmená, index gin\_trgm\_ops (pg\_trgm) na ňom sa použije a vyhľadávanie vo viacerých stĺpcoch použije jeden index na stĺpec (BitmapOr), ak ho má každý z nich. lower(col) like ? — čo zvyčajne píšu ručne robené vyhľadávacie callbacky — index stĺpca použiť vôbec nevie. Do asText uvádzajte len netextové stĺpce; omylom uvedený varchar na PostgreSQL nič nestojí (merané na PostgreSQL 16: "title"::text ilike ? aj "title" ilike ? dajú rovnaký plán, oba nad indexom). pg\_trgm potrebuje aspoň 3 znaky, aby výsledky vôbec zúžil.

## Relácie a chyby v deklarácii

- Žiadne vyhľadávanie v reláciách — bodka je kvalifikátor tabuľky (posts.title), ako všade v balíku. Ak chcete prehľadať súvisiacu tabuľku, pripojte ju cez join a stĺpce kvalifikujte, alebo použite callback s whereHas.
- Chybná deklarácia vyhodí InvalidFilterDeclaration (LogicException) už pri vytvorení filtra: žiadne stĺpce, stĺpec, ktorý nie je holý ani tabuľkou kvalifikovaný názov (tags::text, lower(name), name as n — namiesto pretypovania použite asText), alebo stĺpec v asText, ktorý filter neprehľadáva.
- Duplicitné stĺpce sa odstránia, poradie ostane zachované.

## Priame použitie SearchFilter

RoundlyConsulting\\QueryBuilder\\Filters\\SearchFilter — new SearchFilter(array $columns, array $asText = \[\]) — je to, čo obaľuje AllowedFilter::search(). Zaregistrujte ho pod iným názvom cez AllowedFilter::custom() alebo ho použite mimo filter\[\] pre samostatný parameter ?search=:

```php
use RoundlyConsulting\QueryBuilder\AllowedFilter;
use RoundlyConsulting\QueryBuilder\Filters\SearchFilter;

// The same filter under another wire name:
->allowedFilters(AllowedFilter::custom('q', new SearchFilter(['users.name', 'users.email'])))

// Outside filter[], for a top-level ?search= contract:
(new SearchFilter(['name', 'email']))->apply($query, $request->string('search')->toString(), 'search');
```

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/query-builder-for-laravel.md)
