NGRAM
Milvus의 NGRAM 인덱스는 VARCHAR 필드 또는 JSON 필드 내의 특정 JSON 경로에 대한 LIKE 쿼리를 가속화하기 위해 구축되었습니다. 인덱스를 구축하기 전에 Milvus는 텍스트를 n-그램이라고 하는 고정된 길이 n의 짧고 겹치는 하위 문자열로 분할합니다. 예를 들어, n = 3이면 "Milvus "라는 단어는 3그램으로 분할됩니다: "Mil", "ilv", "lvu", "vus". 그런 다음 이러한 n-그램은 각 그램을 해당 그램이 나타나는 문서 ID에 매핑하는 반전 인덱스에 저장됩니다. 쿼리 시 이 인덱스를 통해 Milvus는 검색 범위를 작은 후보 집합으로 빠르게 좁힐 수 있으므로 쿼리 실행 속도가 훨씬 빨라집니다.
다음과 같이 빠른 접두사, 접미사, 접미사 또는 와일드카드 필터링이 필요할 때 이 색인을 사용하세요:
name LIKE "data%"title LIKE "%vector%"path LIKE "%json"
필터 표현식 구문에 대한 자세한 내용은 기본 연산자를 참조하세요.
작동 방식
Milvus는 NGRAM 인덱스를 2단계 프로세스로 구현합니다:
인덱스를 구축합니다: 각 문서에 대해 n-그램을 생성하고 수집 중에 반전된 인덱스를 구축합니다.
쿼리 가속화: 인덱스를 사용하여 작은 후보 집합으로 필터링한 다음 정확히 일치하는 것을 확인합니다.
1단계: 색인 구축
데이터 수집 중에 Milvus는 두 가지 주요 단계를 수행하여 NGRAM 인덱스를 구축합니다:
텍스트를 N-그램으로 분해합니다: Milvus는 대상 필드의 각 문자열에 걸쳐 n의 창을 슬라이드하고 겹치는 하위 문자열, 즉 n-그램을 추출합니다. 이러한 하위 문자열의 길이는 구성 가능한 범위인
[min_gram, max_gram].min_gram: 생성할 최단 n-그램입니다. 또한 인덱스를 활용할 수 있는 최소 쿼리 하위 문자열 길이를 정의합니다.max_gram: 생성할 가장 긴 n-그램. 쿼리 시에는 긴 쿼리 문자열을 분할할 때 최대 창 크기로도 사용됩니다.
예를 들어
min_gram=2와max_gram=3의 경우"AI database"문자열은 다음과 같이 분할됩니다:
Ngram 인덱스 구축
- **2-grams:** `AI`, `I_`, `_d`, `da`, `at`, ...
- **3-grams:** `AI_`, `I_d`, `_da`, `dat`, `ata`, ...
<div class="alert note">
- For a range `[min_gram, max_gram]`, Milvus generates all n-grams for every length between the two values (inclusive). For example, with `[2,4]` and the word `"text"`, Milvus generates:
- **2-grams:** `te`, `ex`, `xt`
- **3-grams:** `tex`, `ext`
- **4-grams:** `text`
- N-gram decomposition is character-based and language-agnostic. For example, in Chinese, `"向量数据库"` with `min_gram = 2` is decomposed into: `"向量"`, `"量数"`, `"数据"`, `"据库"`.
- Spaces and punctuation are treated as characters during decomposition.
- Decomposition preserves original case, and matching is case-sensitive. For example, `"Database"` and `"database"` will generate different n-grams and require exact case matching during queries.
</div>
역 인덱스를 구축합니다: 생성된 각 n-그램을 이를 포함하는 문서 ID 목록에 매핑하는 반전 인덱스가 생성됩니다.
예를 들어 2그램
"AI"이 ID가 1, 5, 6, 8, 9인 문서에 나타나면 인덱스는{"AI": [1, 5, 6, 8, 9]}을 기록합니다. 그런 다음 쿼리 시 이 인덱스를 사용하여 검색 범위를 빠르게 좁힙니다.
Ngram 색인 2 구축
<div class="alert note">
A wider `[min_gram, max_gram]` range creates more grams and larger mapping lists. If memory is tight, consider mmap mode for very large posting lists. For details, refer to [Use mmap](https://zilliverse.feishu.cn/wiki/P3wrwSMNNihy8Vkf9p6cTsWYnTb).
</div>
2단계: 쿼리 가속화
LIKE 필터가 실행되면 Milvus는 다음 단계에서 NGRAM 인덱스를 사용하여 쿼리를 가속화합니다:
쿼리 가속화
쿼리 용어를 추출합니다:
LIKE표현식에서 와일드카드가 없는 연속된 하위 문자열을 추출합니다(예:"%database%"은"database"이 됩니다).쿼리 용어를 분해합니다: 쿼리 용어는 길이(
L)와min_gram및max_gram설정에 따라 n-그램으로 분해됩니다.L < min_gram인 경우 인덱스를 사용할 수 없으며 쿼리는 전체 검색으로 돌아갑니다.min_gram ≤ L ≤ max_gram인 경우 전체 쿼리 용어는 단일 n-그램으로 처리되며 더 이상 분해할 필요가 없습니다.L > max_gram인 경우 쿼리 용어는max_gram과 같은 창 크기를 사용하여 겹치는 그램으로 분해됩니다.
예를 들어
max_gram이3으로 설정되어 있고 쿼리 용어의 길이가 8 인"database"인 경우"dat","ata","tab"등과 같은 3 그램 하위 문자열로 분해됩니다.각 그램 찾기 및 교차: Milvus는 역 인덱스에서 각 쿼리 그램을 찾은 다음 결과 문서 ID 목록과 교차하여 작은 후보 문서 세트를 찾습니다. 이러한 후보 문서에는 쿼리의 모든 문형이 포함됩니다.
결과를 확인하고 반환합니다: 그런 다음 원본
LIKE필터를 작은 후보 집합에만 최종 검사로 적용하여 정확히 일치하는 것을 찾습니다.
NGRAM 색인 만들기
VARCHAR 필드 또는 JSON 필드 내의 특정 경로에 NGRAM 인덱스를 만들 수 있습니다.
예 1: VARCHAR 필드에 생성하기
VARCHAR 필드의 경우 field_name 을 지정하고 min_gram 및 max_gram 을 구성하기만 하면 됩니다.
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530") # Replace with your server address
# Assume you have defined a VARCHAR field named "text" in your collection schema
# Prepare index parameters
index_params = client.prepare_index_params()
# Add NGRAM index on the "text" field
index_params.add_index(
field_name="text", # Target VARCHAR field
index_type="NGRAM", # Index type is NGRAM
index_name="ngram_index", # Custom name for the index
min_gram=2, # Minimum substring length (e.g., 2-gram: "st")
max_gram=3 # Maximum substring length (e.g., 3-gram: "sta")
)
# Create the index on the collection
client.create_index(
collection_name="Documents",
index_params=index_params
)
이 구성은 text 의 각 문자열에 대해 2그램과 3그램을 생성하고 이를 반전된 인덱스에 저장합니다.
예 2: JSON 경로에 생성하기
JSON 필드의 경우 그램 설정 외에도 해당 필드를 가리키는
params.json_path- 색인하려는 값을 가리키는 JSON 경로.params.json_cast_type- NGRAM 인덱싱은 문자열에서 작동하므로"varchar"(대소문자를 구분하지 않음)이어야 합니다.
# Assume you have defined a JSON field named "json_field" in your collection schema, with a JSON path named "body"
# Prepare index parameters
index_params = client.prepare_index_params()
# Add NGRAM index on a JSON field
index_params.add_index(
field_name="json_field", # Target JSON field
index_type="NGRAM", # Index type is NGRAM
index_name="json_ngram_index", # Custom index name
min_gram=2, # Minimum n-gram length
max_gram=4, # Maximum n-gram length
params={
"json_path": "json_field[\"body\"]", # Path to the value inside the JSON field
"json_cast_type": "varchar" # Required: cast the value to varchar
}
)
# Create the index on the collection
client.create_index(
collection_name="Documents",
index_params=index_params
)
이 예제에서는
json_field["body"]의 값만 색인됩니다.이 값은 n-gram 토큰화 전에
VARCHAR로 캐스팅됩니다.Milvus는 길이 2~4의 하위 문자열을 생성하고 이를 반전된 인덱스에 저장합니다.
JSON 필드를 색인하는 방법에 대한 자세한 내용은 JSON 색인하기를 참조하세요.
NGRAM으로 가속화된 쿼리
NGRAM 인덱스를 적용하려면:
쿼리는
NGRAM인덱스가 있는VARCHAR필드(또는 JSON 경로)를 대상으로 해야 합니다.LIKE패턴의 리터럴 부분은min_gram문자 이상이어야 합니다.(예를 들어 예상되는 최단 쿼리 용어가 2자인 경우 인덱스를 만들 때 min_gram=2로 설정합니다.)
지원되는 쿼리 유형:
접두사 일치
# Match any string that starts with the substring "database" filter = 'text LIKE "database%"'접미사 일치
# Match any string that ends with the substring "database" filter = 'text LIKE "%database"'접미사 일치
# Match any string that contains the substring "database" anywhere filter = 'text LIKE "%database%"'와일드카드 일치
Milvus는
%(0자 이상)와_(정확히 한 글자)를 모두 지원합니다.# Match any string where "st" appears first, and "um" appears later in the text filter = 'text LIKE "%st%um%"'JSON 경로 쿼리
filter = 'json_field["body"] LIKE "%database%"'
필터 표현식 구문에 대한 자세한 내용은 기본 연산자를 참조하세요.
색인 삭제
컬렉션에서 기존 인덱스를 제거하려면 drop_index() 메서드를 사용합니다.
client.drop_index(
collection_name="Documents", # Name of the collection
index_name="ngram_index" # Name of the index to drop
)
사용 참고 사항
필드 유형:
VARCHAR및JSON필드에서 지원됩니다. JSON의 경우params.json_path와params.json_cast_type="varchar"을 모두 제공하세요.유니코드: NGRAM 분해는 문자 기반이며 언어에 구애받지 않고 공백과 구두점을 포함합니다.
시공간 균형: 더 넓은 그램 범위(
[min_gram, max_gram])는 더 많은 그램과 더 큰 인덱스를 생성합니다. 메모리가 부족하다면 큰 글 목록에 대해mmap모드를 고려하세요. 자세한 내용은 mmap 사용을 참조하세요.불변성:
min_gram및max_gram은 제자리에서 변경할 수 없으며 인덱스를 다시 작성하여 조정해야 합니다.
모범 사례
검색 동작에 맞게 최소 그램 및 최대 그램을 선택합니다.
min_gram=2,max_gram=3로 시작합니다.min_gram을 사용자가 입력할 것으로 예상되는 가장 짧은 리터럴로 설정합니다.의미 있는 하위 문자열의 일반적인 길이에 가까운
max_gram을 설정하고,max_gram을 크게 설정하면 필터링이 향상되지만 공간이 늘어납니다.
선택성이 낮은 그램 피하기
매우 반복적인 패턴(예:
"aaaaaa")은 필터링이 약하고 이득이 제한적일 수 있습니다.일관된 정규화
사용 사례에 필요한 경우 수집된 텍스트와 쿼리 리터럴에 동일한 정규화(예: 소문자, 트리밍)를 적용하세요.