검색 쿼리

검색 쿼리 (Search with POST)

검색은 Meilisearch의 핵심 기능이에요. POST /indexes/{index_uid}/search 엔드포인트에 쿼리와 함께 갖가지 파라미터를 실어 보내면, Meilisearch가 문서를 검색해 매칭 결과와 메타데이터를 돌려줍니다. 이 페이지에서는 검색 요청의 본문(body) 파라미터들을 하나씩 살펴볼게요. 어떤 파라미터가 무엇을 조절하는지 알면, 원하는 검색 UX를 훨씬 정확하게 만들 수 있어요.

출처: Meilisearch 공식 문서 — Search with POST

본문

인증

API를 호출할 때는 Authorization 헤더에 API 키를 포함해 주세요:

 -H 'Authorization: Bearer 6436fc5237b0d6e0d64253fbaac21d135012ecf1'

SDK를 쓴다면 클라이언트를 인스턴스화할 때 API 키를 지정합니다:

 const client = new MeiliSearch ({ host: 'MEILISEARCH_URL' , apiKey: '6436fc5237b0d6e0d64253fbaac21d135012ecf1' });

경로 파라미터

  • index_uid (string, 필수): 인덱스의 고유 식별자입니다.

본문 파라미터 (Body)

q — 검색어

string | null. 검색어를 설정합니다. Meilisearch는 이 쿼리와 일치하는 문서를 반환해요. 쿼리는 접두사 검색오타 허용을 지원합니다. Meilisearch는 처음 열 개 단어만 고려하며, 단어는 정규화됩니다(소문자, 악센트 무시).

생략하거나 비워 두면 플레이스홀더 검색(placeholder search)이 돼요 — 쿼리 용어가 적용되지 않으므로, 인덱스의 모든 검색 가능한 문서를 랭킹 규칙 순서로 반환합니다.

단어를 큰따옴표(")로 감싸면 구문 검색(phrase search)이 돼요: 정확히 그 단어 시퀀스를 포함하는 문서만 반환됩니다 (예: "Winter Feast"). 단어나 구 앞에 마이너스 부호(-)를 붙이면 결과에서 제외할 수 있어요.

offset — 건너뛸 문서 수

integer, 기본값 0. 결과 시작 부분에서 건너뛸 문서 수입니다. limit과 함께 페이지네이션에 사용해요 (예: offset=20이고 limit=20이면 결과 21~40을 반환). pagehitsPerPage가 설정되면 이 파라미터는 무시되며, 그 경우 응답에는 estimatedTotalHits 대신 totalHitstotalPages가 포함됩니다. 범위: x >= 0

limit — 반환 문서 수

integer, 기본값 20. 응답에서 반환할 최대 문서 수입니다. offset과 함께 페이지네이션에 쓰여요. pagehitsPerPage가 설정되면 무시됩니다. 값은 인덱스의 maxTotalHits 설정을 초과할 수 없어요. 범위: x >= 0

page — 페이지 요청

integer | null. 특정 결과 페이지를 요청합니다(1-인덱스). hitsPerPage와 함께 사용해요. 설정되면 응답에 estimatedTotalHits 대신 totalHitstotalPages가 포함됩니다. pagehitsPerPageoffsetlimit보다 우선해요. 범위: x >= 0

hitsPerPage — 페이지당 문서 수

integer | null. 페이지네이션을 위한 페이지당 최대 문서 수입니다. 이 값이 totalPages를 결정하며 page와 함께 사용해요. 설정되면 응답에 totalHitstotalPages가 포함됩니다. 0으로 설정하면 문서를 반환하지 않으면서 정확한 totalHits 개수를 얻을 수 있어요. 범위: x >= 0

attributesToRetrieve — 반환할 속성 목록

string[] | null. 반환되는 각 문서에 포함할 속성 목록입니다. ["*"]를 쓰면 모든 속성을 반환하고, 설정하지 않으면 인덱스의 displayed attributes 목록을 사용해요. displayedAttributes에 없는 속성은 응답에서 생략됩니다.

attributesToCrop — 크롭할 속성

string[] | null. 값이 짧은 발췌문으로 크롭되어야 하는 속성입니다. 크롭된 텍스트는 각 hit의 _formatted 객체에 나타나요. 길이는 cropLength로 제어하거나, attribute:length 구문으로 속성별로 재정의할 수 있습니다. ["*"]를 쓰면 attributesToRetrieve의 모든 속성을 크롭해요. 가능하면 크롭은 매칭 용어 주변을 중심으로 이뤄집니다.

cropLength — 크롭 길이

integer, 기본값 10. 크롭된 값에 포함할 최대 단어 수입니다. attributesToCrop이 설정된 경우에만 적용돼요. 쿼리 용어와 stop words 모두 이 길이에 포함됩니다. 범위: x >= 0

cropMarker — 크롭 경계 표시

string, 기본값 . 크롭된 텍스트에서 크롭 경계를 표시하는 문자열입니다. null이거나 비어 있으면 표시 기호가 삽입되지 않아요. 표시 기호는 콘텐츠가 실제로 제거된 곳에만 추가됩니다.

attributesToHighlight — 하이라이트할 속성

string[] | null. 매칭 쿼리 용어가 하이라이트되어야 하는 속성입니다. 하이라이트된 텍스트는 각 hit의 _formatted 객체에 나타나요. ["*"]를 쓰면 attributesToRetrieve의 모든 속성을 하이라이트합니다. 기본적으로 매치는 <em></em>로 감싸지며, highlightPreTaghighlightPostTag로 재정의할 수 있어요. 하이라이트는 동의어stop words에도 적용됩니다. 지원되는 값 타입은 string, number, array, object예요. searchableAttributes에 없는 속성까지 포함해, 나열된 모든 속성 내 매치를 하이라이트한다는 점에 주의하세요.

highlightPreTag / highlightPostTag — 하이라이트 태그

highlightPreTag: string, 기본값 <em>. 각 하이라이트 용어 앞에 삽입할 문자열입니다. 어떤 문자열이든 가능해요 (예: <strong>, *). null이거나 비어 있으면 매치 시작에 아무것도 삽입되지 않아요.

highlightPostTag: string, 기본값 </em>. 각 하이라이트 용어 뒤에 삽입할 문자열입니다. 잘못된 출력(예: 닫히지 않은 HTML 태그)을 피하려면 highlightPreTag와 함께 사용해야 해요.

showMatchesPosition — 매치 위치 표시

boolean. true로 설정하면 각 hit에 매치된 각 용어의 바이트 오프셋(startlength)을 담은 _matchesPosition 객체가 포함됩니다. 커스텀 하이라이팅이 필요할 때 유용해요. 검색 가능하지 않은 속성을 포함해 모든 속성의 매치 위치를 보고하며, 위치는 문자(character)가 아니라 바이트로 측정됩니다.

filter — 필터 표현식

any. 결과를 좁히는 필터 표현식입니다. 표현식에 사용된 모든 속성은 filterableAttributes에 있어야 해요.

문자열을 넘길 수 있고 (예: "(genres = horror OR genres = mystery) AND director = 'Jordan Peele'"), 배열로도 넘길 수 있어요 (예: [["genres = horror", "genres = mystery"], "director = 'Jordan Peele'"]). 지리 검색에는 _geoRadius(lat, lng, distance_in_meters), _geoBoundingBox([lat,lng],[lat,lng]), _geoPolygon([lat,lng], ...)을 사용합니다 (polygon은 GeoJSON만 지원).

sort — 정렬

string[] | null. 하나 이상의 속성과 그 순서로 결과를 정렬합니다. ["attribute:asc", "attribute:desc"] 형식을 쓰며, sortableAttributes에 있는 속성만 사용할 수 있어요. 지리 검색에는 _geoPoint(lat,lng):asc 또는 :desc를 쓰고, 응답에는 미터 단위의 _geoDistance가 포함됩니다. 목록의 첫 번째 속성이 우선권을 가져요.

distinct — 중복 제거

string | null. 주어진 속성의 고유 값당 문서 하나만 반환합니다 (예: product_id로 중복 제거). 속성은 filterableAttributes에 있어야 해요. 이 값은 이 요청에서 인덱스의 distinctAttribute 설정을 재정의합니다.

facets — 패싯 분포

null | object. 나열된 속성의 패싯 값별 매치 수를 반환합니다. 응답에는 facetDistribution과, 숫자 패싯의 경우 facetStats(min/max)가 포함돼요. 이 라우트는 "title", "dogs.*", "*" 같은 패턴도 지원하며, filterableAttributes에 매칭될 수 있습니다. 패싯별 반환 값 수는 인덱스의 maxValuesPerFacet 설정에 의해 제한되며, filterableAttributes에 없는 속성은 무시됩니다.

matchingStrategy — 매칭 전략

enum<string>. limit을 충족할 만큼 결과가 없을 때 쿼리 용어를 어떻게 매칭할지 정합니다.

  • last: 모든 쿼리 용어를 포함하는 문서를 먼저 반환합니다. 그런 결과가 충분하지 않으면 쿼리 끝에서부터 용어를 하나씩 제거해요 (예: "big fat cat" → "big fat" → "big").
  • all: 모든 쿼리 용어를 포함하는 문서만 반환합니다. limit보다 적은 문서가 매칭돼도 쿼리를 완화하지 않아요.
  • frequency: 모든 쿼리 용어를 포함하는 문서를 먼저 반환합니다. 부족하면 데이터셋에서 가장 빈번한 단어부터 하나씩 제거해, 희귀한 용어에 더 가중치를 줍니다 (예: "white cotton shirt"에서 "shirt"가 매우 흔하면 "white"를 포함하는 문서를 우선).

기본값: last.

attributesToSearchOn — 검색 속성 제한

string[] | null. 나열된 속성에서만 검색하도록 제한합니다. 각 속성은 인덱스의 searchable attributes 목록에 있어야 해요. 이 파라미터의 속성 순서는 관련성에 영향을 주지 않습니다.

rankingScoreThreshold — 랭킹 점수 임계값

number<double> | null. 랭킹 점수(0.0과 1.0 사이)가 이 값보다 낮은 문서를 결과에서 제외합니다. 제외된 hit은 estimatedTotalHits, totalHits, 패싯 분포에 포함되지 않아요. pagehitsPerPage와 함께 쓰면 Meilisearch가 모든 일치 문서를 채점해야 하므로 성능이 저하될 수 있습니다.

locales — 쿼리 언어 명시

enum<string>[] | null. 쿼리의 언어를 명시적으로 지정합니다. 지원되는 ISO-639 로케일 배열을 넘겨요. 자동 감지를 재정의하며, 쿼리나 문서에 대해 자동 감지가 틀릴 때 사용합니다 (예: ko, en, ar 등).

hybrid — 하이브리드 검색

null | object. 하이브리드 검색: 키워드 검색과 의미 검색을 결합합니다. embedder 필드(필수)는 인덱스 설정의 임베더 이름과 일치해야 해요. semanticRatio 필드는 균형을 조절합니다: 0.0은 키워드 전용 결과, 1.0은 의미 전용 결과예요. q가 비어 있고 semanticRatio가 0보다 크면 순수 의미 검색을 수행합니다. semanticRatio의 기본값은 0.5입니다.

vector — 커스텀 쿼리 벡터

number<float>[] | null. 벡터 또는 하이브리드 검색을 위한 커스텀 쿼리 벡터입니다. 배열 길이는 인덱스에 구성된 임베더의 차원과 일치해야 해요. user-provided embedder를 사용할 때는 이 파라미터가 필수입니다. hybrid와 함께 쓰면 문서가 벡터 유사도로 랭킹됩니다.

retrieveVectors — 벡터 반환

boolean. true로 설정하면 응답에 각 hit의 _vectors 필드에 문서와 쿼리 임베딩이 포함됩니다. _vectors 필드가 나타나려면 displayedAttributes에 나열되어 있어야 해요.

showRankingScore — 랭킹 점수 표시

boolean. true로 설정하면 각 문서에 0.0과 1.0 사이의 _rankingScore가 포함되는데, 값이 클수록 문서가 더 관련성이 높다는 뜻이에요. sort 랭킹 규칙은 _rankingScore 값에 영향을 주지 않습니다.

showRankingScoreDetails — 랭킹 점수 상세

boolean. true로 설정하면 각 문서에 각 랭킹 규칙의 점수 기여도를 분해한 _rankingScoreDetails가 포함됩니다. 관련성 디버깅에 유용해요.

showPerformanceDetails — 성능 상세

boolean. true로 설정하면 응답에 쿼리 처리의 단계별 시간 분해를 담은 performanceDetails 객체가 포함됩니다.

응답 (Response)

검색 응답에는 매칭 문서와 메타데이터가 담깁니다. 핵심 필드들:

  • hits (object[]): 매칭 문서. 각 hit에는 문서 필드가 들어 있고, 요청 시 _formatted, _matchesPosition, _rankingScore, _rankingScoreDetails, _geoDistance가 포함됩니다.
  • query (string): 이 응답을 만들어낸 쿼리 문자열.
  • processingTimeMs (integer): 쿼리 처리에 걸린 시간(밀리초).
  • totalHits (integer): 매칭된 전체 문서 수. page/hitsPerPage 사용 시 estimatedTotalHits 대신 반환됩니다.
  • hitsPerPage (integer): 페이지당 결과 수.
  • page (integer): 현재 페이지 인덱스(1-기반).
  • totalPages (integer): 전체 결과 페이지 수.
  • facetDistribution (object | null): 요청된 각 패싯에 대한 패싯 값별 매칭 문서 수. facets가 설정된 경우 존재.
  • facetStats (object | null): 숫자 패싯의 최소·최대 값. facets가 설정된 경우 존재.
  • queryVector (number<float>[] | null): 검색에 사용된 쿼리 임베딩. 벡터 또는 하이브리드 검색 시 존재.
  • requestUid (string<uuid> | null): 이 검색 요청을 식별하는 UUID v7.
  • semanticHitCount (integer | null): 의미 검색 매치의 정확한 개수. AI 기반(하이브리드/의미) 검색에만 존재.

더 알아보기