검색

번역일: 2026년 6월 25일

검색

소개

거의 모든 애플리케이션에는 검색 기능이 필요합니다. 사용자가 지식 베이스에서 관련 글을 찾거나, 상품 카탈로그를 탐색하거나, 문서 모음에 자연어로 질문을 던지는 등 다양한 시나리오에서 Laravel은 이를 처리할 수 있는 내장 도구를 제공합니다. 대부분의 경우 외부 서비스 없이도 충분히 구현할 수 있습니다.

많은 애플리케이션에서 Laravel이 기본으로 제공하는 데이터베이스 기반 검색만으로도 충분합니다. 오타 허용, 패싯 필터링, 대규모 지역 검색과 같은 기능이 필요할 때만 외부 검색 서비스를 고려하면 됩니다.

검색어와의 일치도를 기준으로 데이터베이스가 결과를 점수화하고 정렬하는 키워드 관련성 랭킹이 필요하다면, Laravel의 whereFullText 쿼리 빌더 메서드를 사용하세요. 이 메서드는 MariaDB, MySQL, PostgreSQL의 네이티브 전문 인덱스를 활용합니다. 전문 검색은 단어 경계와 어간(stemming)을 이해하므로, "running"을 검색하면 "run"이 포함된 레코드도 매칭됩니다. 외부 서비스가 필요 없습니다.

정확한 키워드 일치가 아닌 의미 기반으로 결과를 매칭하는 AI 기반 시맨틱 검색이 필요하다면, whereVectorSimilarTo 쿼리 빌더 메서드를 사용하세요. 이 메서드는 pgvector 확장이 설치된 PostgreSQL에 저장된 벡터 임베딩을 활용합니다. 예를 들어 "나파 밸리의 최고 와이너리"를 검색하면, 단어가 전혀 겹치지 않아도 "꼭 방문해야 할 포도원 TOP 10" 같은 글이 검색 결과에 나타날 수 있습니다. 벡터 검색을 사용하려면 pgvector 확장이 설치된 PostgreSQL과 Laravel AI SDK가 필요합니다.

리랭킹 (Reranking)

Laravel의 AI SDK는 AI 모델을 사용해 임의의 결과 집합을 쿼리와의 시맨틱 관련성 기준으로 재정렬하는 리랭킹 기능을 제공합니다. 리랭킹은 전문 검색 같은 빠른 1차 검색 이후의 2단계 처리로 활용할 때 특히 강력합니다. 속도와 시맨틱 정확도를 동시에 얻을 수 있습니다.

Laravel Scout 검색

Eloquent 모델과 검색 인덱스를 자동으로 동기화하는 Searchable 트레이트를 원한다면, Laravel Scout를 사용하세요. Scout는 내장 데이터베이스 엔진은 물론 Algolia, Meilisearch, Typesense 같은 서드파티 서비스 드라이버도 지원합니다.

LIKE 쿼리는 단순한 부분 문자열 매칭에는 잘 동작하지만, 언어를 이해하지는 못합니다. "running"으로 LIKE 검색을 해도 "run"이 포함된 레코드는 찾지 못하며, 결과가 관련성 순으로 정렬되지도 않습니다. 전문 검색은 단어 경계, 어간, 관련성 점수를 이해하는 특수 인덱스를 사용해 이 두 가지 문제를 모두 해결하고, 가장 관련성 높은 결과를 먼저 반환합니다.

MariaDB, MySQL, PostgreSQL에는 고속 전문 검색이 내장되어 있으므로 외부 서비스가 필요 없습니다. 검색할 컬럼에 전문 인덱스를 추가하고 whereFullText 쿼리 빌더 메서드를 사용하기만 하면 됩니다.

WARNING

전문 검색은 현재 MariaDB, MySQL, PostgreSQL에서 지원됩니다.

전문 인덱스 추가하기

전문 검색을 사용하려면 먼저 검색할 컬럼에 전문 인덱스를 추가하세요. 단일 컬럼에 추가하거나, 여러 컬럼을 배열로 전달해 복합 인덱스를 생성할 수 있습니다. 복합 인덱스를 사용하면 여러 필드를 한 번에 검색할 수 있습니다:

Schema::create('articles', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('body'); $table->timestamps(); $table->fullText(['title', 'body']); });

PostgreSQL에서는 단어 어간 처리 방식을 제어하는 언어 설정을 지정할 수 있습니다:

$table->fullText('body')->language('english');

인덱스 생성에 대한 자세한 내용은 마이그레이션 문서를 참고하세요.

전문 검색 쿼리 실행하기

인덱스를 추가했다면 whereFullText 쿼리 빌더 메서드로 검색을 실행하세요. Laravel은 데이터베이스 드라이버에 맞는 SQL을 자동으로 생성합니다. MariaDB와 MySQL에서는 MATCH(...) AGAINST(...), PostgreSQL에서는 to_tsvector(...) @@ plainto_tsquery(...)가 사용됩니다:

$articles = Article::whereFullText('body', '웹 개발자')->get();

MariaDB와 MySQL에서는 결과가 관련성 점수 순으로 자동 정렬됩니다. PostgreSQL에서는 whereFullText가 일치하는 레코드를 필터링하지만 관련성 순으로 정렬하지는 않습니다. PostgreSQL에서 자동 관련성 정렬이 필요하다면 Scout의 데이터베이스 엔진 사용을 고려하세요.

여러 컬럼에 걸친 복합 전문 인덱스를 생성했다면, 동일한 컬럼 배열을 whereFullText에 전달해 모든 컬럼을 대상으로 검색할 수 있습니다:

$articles = Article::whereFullText( ['title', 'body'], '웹 개발자' )->get();

orWhereFullText 메서드를 사용하면 전문 검색 조건을 "or" 조건으로 추가할 수 있습니다. 자세한 내용은 쿼리 빌더 문서를 참고하세요.

전문 검색은 키워드 매칭에 의존합니다. 즉, 쿼리의 단어가 데이터에 어떤 형태로든 존재해야 합니다. 시맨틱 검색은 근본적으로 다른 접근법을 취합니다. AI가 생성한 벡터 임베딩으로 텍스트의 의미를 숫자 배열로 표현하고, 쿼리의 의미와 가장 유사한 결과를 찾습니다. 예를 들어 "나파 밸리의 최고 와이너리"를 검색하면, 단어가 전혀 겹치지 않더라도 "꼭 방문해야 할 포도원 TOP 10" 같은 글이 검색될 수 있습니다.

벡터 검색의 기본 흐름은 다음과 같습니다. 각 콘텐츠에 대한 임베딩(숫자 배열)을 생성해 데이터와 함께 저장하고, 검색 시점에 사용자 쿼리에 대한 임베딩을 생성한 뒤 벡터 공간에서 가장 가까운 저장된 임베딩을 찾습니다.

NOTE

벡터 검색을 사용하려면 pgvector 확장이 설치된 PostgreSQL 데이터베이스와 Laravel AI SDK가 필요합니다. Laravel Cloud의 모든 Serverless Postgres 데이터베이스에는 pgvector가 기본 포함되어 있습니다.

임베딩 생성하기

임베딩은 텍스트의 시맨틱 의미를 나타내는 고차원 숫자 배열(일반적으로 수백~수천 개의 숫자)입니다. Laravel의 Stringable 클래스에서 제공하는 toEmbeddings 메서드를 사용해 문자열에 대한 임베딩을 생성할 수 있습니다:

use Illuminate\Support\Str; $embedding = Str::of('Laravel은 PHP 웹 프레임워크입니다.')->toEmbeddings();

여러 입력에 대한 임베딩을 한 번에 생성하려면 Embeddings 클래스를 사용하세요. 임베딩 제공자에 대한 API 호출이 한 번만 이루어지므로 하나씩 생성하는 것보다 훨씬 효율적입니다:

use Laravel\Ai\Embeddings; $response = Embeddings::for([ '나파 밸리에는 훌륭한 와인이 있습니다.', 'Laravel은 PHP 프레임워크입니다.', ])->generate(); $response->embeddings; // [[0.123, 0.456, ...], [0.789, 0.012, ...]]

임베딩 제공자 설정, 차원 커스터마이징, 캐싱에 대한 자세한 내용은 AI SDK 문서를 참고하세요.

벡터 저장 및 인덱싱

벡터 임베딩을 저장하려면 마이그레이션에서 vector 컬럼을 정의하고, 사용하는 임베딩 제공자의 출력에 맞는 차원 수를 지정하세요(예: OpenAI의 text-embedding-3-small 모델은 1536차원). 또한 컬럼에 index를 호출해 HNSW(Hierarchical Navigable Small World) 인덱스를 생성하세요. 이 인덱스는 대용량 데이터셋에서 유사도 검색 속도를 크게 향상시킵니다:

Schema::ensureVectorExtensionExists(); Schema::create('documents', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('content'); $table->vector('embedding', dimensions: 1536)->index(); $table->timestamps(); });

Schema::ensureVectorExtensionExists 메서드는 테이블 생성 전에 PostgreSQL 데이터베이스에 pgvector 확장이 활성화되어 있는지 확인합니다.

Eloquent 모델에서는 벡터 컬럼을 array로 캐스팅하여, Laravel이 PHP 배열과 데이터베이스의 벡터 형식 간 변환을 자동으로 처리하도록 합니다:

protected function casts(): array { return [ 'embedding' => 'array', ]; }

벡터 컬럼과 인덱스에 대한 자세한 내용은 마이그레이션 문서를 참고하세요.

유사도 기반 쿼리

콘텐츠에 대한 임베딩을 저장했다면, whereVectorSimilarTo 메서드를 사용해 유사한 레코드를 검색할 수 있습니다. 이 메서드는 코사인 유사도를 사용해 주어진 임베딩을 저장된 벡터와 비교하고, minSimilarity 임계값 미만의 결과를 필터링하며, 가장 유사한 레코드가 먼저 오도록 자동으로 결과를 정렬합니다. 임계값은 0.0에서 1.0 사이의 값이며, 1.0은 두 벡터가 완전히 동일함을 의미합니다:

$documents = Document::query() ->whereVectorSimilarTo('embedding', $queryEmbedding, minSimilarity: 0.4) ->limit(10) ->get();

편의를 위해 임베딩 배열 대신 일반 문자열을 전달하면, Laravel이 설정된 임베딩 제공자를 사용해 자동으로 임베딩을 생성합니다. 즉, 사용자의 검색어를 직접 전달할 수 있습니다:

$documents = Document::query() ->whereVectorSimilarTo('embedding', '나파 밸리 최고의 와이너리') ->limit(10) ->get();

더 세밀한 제어가 필요하다면 whereVectorDistanceLessThan, selectVectorDistance, orderByVectorDistance 메서드도 사용할 수 있습니다. 이 메서드들을 사용하면 유사도 점수 대신 거리 값을 직접 다루거나, 계산된 거리를 결과의 컬럼으로 선택하거나, 정렬 방식을 수동으로 제어할 수 있습니다. 자세한 내용은 쿼리 빌더 문서AI SDK 문서를 참고하세요.

결과 리랭킹

리랭킹은 AI 모델이 결과 집합을 주어진 쿼리와의 시맨틱 관련성 순으로 재정렬하는 기법입니다. 임베딩을 미리 계산해 저장해야 하는 벡터 검색과 달리, 리랭킹은 어떤 텍스트 컬렉션에도 적용할 수 있습니다. 원본 콘텐츠와 쿼리를 입력으로 받아 관련성 순으로 정렬된 항목을 반환합니다.

리랭킹은 빠른 1차 검색 이후의 2단계 처리로 활용할 때 특히 강력합니다. 예를 들어 전문 검색으로 수천 개의 레코드를 상위 50개 후보로 빠르게 좁힌 다음, 리랭킹으로 가장 관련성 높은 결과를 상위에 배치하는 식입니다. 이 "검색 후 리랭킹" 패턴은 속도와 시맨틱 정확도를 동시에 제공합니다.

Reranking 클래스를 사용해 문자열 배열을 리랭킹할 수 있습니다:

use Laravel\Ai\Reranking; $response = Reranking::of([ 'Django는 Python 웹 프레임워크입니다.', 'Laravel은 PHP 웹 애플리케이션 프레임워크입니다.', 'React는 사용자 인터페이스를 구축하기 위한 JavaScript 라이브러리입니다.', ])->rerank('PHP 프레임워크'); $response->first()->document; // "Laravel은 PHP 웹 애플리케이션 프레임워크입니다."

Laravel 컬렉션에는 rerank 매크로도 있어, 필드명(또는 클로저)과 쿼리를 받아 Eloquent 결과를 쉽게 리랭킹할 수 있습니다:

$articles = Article::all() ->rerank('body', 'Laravel 튜토리얼');

리랭킹 제공자 설정과 사용 가능한 옵션에 대한 자세한 내용은 AI SDK 문서를 참고하세요.

Laravel Scout

위에서 설명한 검색 기법들은 코드에서 직접 호출하는 쿼리 빌더 메서드입니다. Laravel Scout는 다른 접근법을 취합니다. Eloquent 모델에 추가하는 Searchable 트레이트를 제공하며, Scout가 레코드 생성, 수정, 삭제 시 검색 인덱스를 자동으로 동기화합니다. 인덱스 업데이트를 직접 관리하지 않고도 모델을 항상 검색 가능한 상태로 유지하고 싶을 때 특히 편리합니다.

데이터베이스 엔진

Scout의 내장 데이터베이스 엔진은 기존 데이터베이스를 대상으로 전문 검색과 LIKE 검색을 수행합니다. 외부 서비스나 추가 인프라가 필요 없습니다. 모델에 Searchable 트레이트를 추가하고, 검색 가능하게 만들 컬럼을 반환하는 toSearchableArray 메서드를 정의하기만 하면 됩니다.

PHP 어트리뷰트를 사용해 각 컬럼의 검색 전략을 제어할 수 있습니다. SearchUsingFullText는 데이터베이스의 전문 인덱스를 사용하고, SearchUsingPrefix는 문자열의 시작 부분만 매칭하며(example%), 어트리뷰트가 없는 컬럼은 양쪽에 와일드카드가 있는 기본 LIKE 전략을 사용합니다(%example%):

<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Attributes\SearchUsingFullText; use Laravel\Scout\Attributes\SearchUsingPrefix; use Laravel\Scout\Searchable; class Article extends Model { use Searchable; #[SearchUsingPrefix(['id'])] #[SearchUsingFullText(['title', 'body'])] public function toSearchableArray(): array { return [ 'id' => $this->id, 'title' => $this->title, 'body' => $this->body, ]; } }

WARNING

컬럼에 전문 검색 쿼리 제약 조건을 지정하기 전에, 해당 컬럼에 전문 인덱스가 설정되어 있는지 확인하세요.

트레이트를 추가하면 Scout의 search 메서드로 모델을 검색할 수 있습니다. Scout의 데이터베이스 엔진은 PostgreSQL에서도 결과를 관련성 순으로 자동 정렬합니다:

$articles = Article::search('Laravel')->get();

데이터베이스 엔진은 검색 요구 사항이 중간 수준이고 외부 서비스를 배포하지 않으면서 Scout의 자동 인덱스 동기화 편의성을 원할 때 훌륭한 선택입니다. 필터링, 페이지네이션, 소프트 삭제 레코드 처리를 포함한 가장 일반적인 검색 사용 사례를 잘 처리합니다. 자세한 내용은 Scout 문서를 참고하세요.

서드파티 엔진

Scout는 Algolia, Meilisearch, Typesense 같은 서드파티 검색 엔진도 지원합니다. 이런 전용 검색 서비스는 오타 허용, 패싯 필터링, 지역 검색, 커스텀 랭킹 규칙 같은 고급 기능을 제공합니다. 이런 기능들은 매우 대규모 서비스이거나 정교한 실시간 검색(search-as-you-type) 경험이 필요할 때 중요해집니다.

Scout는 모든 드라이버에 걸쳐 통합된 API를 제공하므로, 나중에 데이터베이스 엔진에서 서드파티 엔진으로 전환할 때 코드 변경이 최소화됩니다. 데이터베이스 엔진으로 시작하고, 애플리케이션의 요구 사항이 데이터베이스가 처리할 수 있는 수준을 초과할 때만 서드파티 서비스로 마이그레이션하면 됩니다.

자세한 내용은 Scout 문서를 참고하세요.

NOTE

많은 애플리케이션은 외부 검색 엔진이 전혀 필요하지 않습니다. 이 페이지에서 설명한 내장 기법들이 대다수의 사용 사례를 충분히 커버합니다.

기법 조합하기

이 페이지에서 설명한 검색 기법들은 상호 배타적이지 않습니다. 오히려 조합할 때 더 좋은 결과를 얻는 경우가 많습니다. 이 도구들이 어떻게 함께 동작하는지 보여주는 두 가지 일반적인 패턴을 소개합니다.

전문 검색 + 리랭킹

전문 검색으로 대용량 데이터셋을 빠르게 후보 집합으로 좁힌 다음, 리랭킹을 적용해 후보들을 시맨틱 관련성 순으로 정렬합니다. 데이터베이스 네이티브 전문 검색의 속도와 AI 기반 관련성 점수의 정확도를 동시에 얻을 수 있습니다:

$articles = Article::query() ->whereFullText('body', $request->input('query')) ->limit(50) ->get() ->rerank('body', $request->input('query'), limit: 10);

벡터 검색 + 일반 필터

벡터 유사도와 일반 where 절을 조합해 시맨틱 검색의 범위를 특정 레코드 집합으로 제한합니다. 의미 기반 검색을 사용하되 소유권, 카테고리 또는 다른 속성으로 결과를 제한해야 할 때 유용합니다:

$documents = Document::query() ->where('team_id', $user->team_id) ->whereVectorSimilarTo('embedding', $request->input('query')) ->limit(10) ->get();

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 6월 25일