Сопоставление шаблонов
В приложениях агентного поиска векторный поиск и сопоставление шаблонов в стиле grep часто дополняют друг друга. Векторный поиск извлекает семантически релевантные объекты, а сопоставление шаблонов сужает эти результаты до точных строковых структур, таких как коды ошибок, префиксы журналов, домены электронной почты, пути URL или идентификаторы.
В Milvus эти ограничения по шаблонам можно задать в скалярных фильтрах с помощью LIKE для простого поиска с подстановочными знаками, а также =~ или !~ для регулярных выражений RE2. Эти фильтры можно комбинировать с query, search или гибридным поиском.
На этой странице описывается сопоставление шаблонов в скалярных выражениях фильтров, используемых в режимах « query », « search » и гибридном поиске. Эти выражения оценивают значения полей и не изменяют токены, сгенерированные анализатором. Для фильтрации токенов во время анализа текста см. раздел «Фильтр Regex Analyzer».
Выражения сопоставления шаблонов записываются в параметре « filter ». Например, следующий запрос находит сообщения журнала, содержащие код ошибки, такой как E1001:
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530")
res = client.query(
collection_name="log_events",
filter='message =~ "E[0-9]{4}"',
output_fields=["message", "severity"],
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;
import java.util.Arrays;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.build());
QueryResp res = client.query(QueryReq.builder()
.collectionName("log_events")
.filter("message =~ \"E[0-9]{4}\"")
.outputFields(Arrays.asList("message", "severity"))
.build());
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
ctx := context.Background()
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: "localhost:19530",
})
if err != nil {
// handle error
}
defer client.Close(ctx)
res, err := client.Query(ctx, milvusclient.NewQueryOption("log_events").
WithFilter(`message =~ "E[0-9]{4}"`).
WithOutputFields("message", "severity"))
if err != nil {
// handle error
}
fmt.Println(res)
const { MilvusClient } = require('@zilliz/milvus2-sdk-node');
async function main() {
const client = new MilvusClient({ address: 'http://localhost:19530' });
const res = await client.query({
collection_name: 'log_events',
filter: 'message =~ "E[0-9]{4}"',
output_fields: ['message', 'severity'],
});
console.log(res);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--data '{
"collectionName": "log_events",
"filter": "message =~ \"E[0-9]{4}\"",
"outputFields": ["message", "severity"]
}'
Примеры на этой странице посвящены выражению, заданному в параметре « filter ». Вы можете использовать тот же синтаксис выражений фильтрации в операциях Milvus, которые поддерживают скалярный фильтр, таких как « query », « search » и гибридный поиск.
Поддерживаемые типы полей
Сопоставление по шаблону доступно для строковых значений.
| Цель | LIKE | Регулярное выражение =~ / !~ | Примечания |
|---|---|---|---|
VARCHAR поле | Да | Да | Типичная цель для сопоставления шаблонов в строковых полях. |
JSON path с типом приведения VARCHAR | Да | Да | Значение JSON-пути должно быть строкой для положительных совпадений. Если вы создаете индекс по JSON-пути для ускорения, установите флаг « json_cast_type="varchar" ». |
ARRAY<VARCHAR> элемент | Да | Да | Сопоставление с конкретным элементом по индексу, например tags[0]. Сопоставление по шаблону не сканирует все элементы; оно применяется только к элементу с указанным индексом. |
Числовые, логические, векторные, TEXT или другие цели, не относящиеся к типу «VARCHAR » | Нет | Нет | Сопоставление по шаблону доступно только для значений типа « VARCHAR », путей JSON, преобразуемых в строки, или индексированных элементов типа « ARRAY<VARCHAR> ». |
Выберите LIKE или регулярное выражение
Выберите самый простой оператор, выражающий нужный вам шаблон.
Если вам требуется точное совпадение строк, мы рекомендуем использовать оператор « == » вместо сопоставления по шаблону. Используйте оператор « LIKE » или регулярное выражение только в том случае, если фильтр должен сопоставляться с шаблоном.
| Требование | Рекомендуемый оператор | Пример | Описание |
|---|---|---|---|
| Точное совпадение строк | == | status == "active" | Точное совпадение строки « active ». |
| Простое совпадение префикса | LIKE | name LIKE "Prod%" | Соответствует строкам, начинающимся со Prod. |
| Простое совпадение суффикса | LIKE | filename LIKE "%.json" | Соответствует строкам, заканчивающимся на .json. |
| Простое совпадение по содержанию | LIKE | description LIKE "%vector database%" | Соответствует значениям, содержащим vector database в любом месте строки. |
| Поиск структурированного кода или шаблона фиксированной длины | =~ | code =~ "E[0-9]{4}" | Соответствует строкам, содержащим (с учетом регистра) E, за которым следуют четыре цифры, например E1001. |
| Сопоставление шаблонов без учета регистра | =~ с (?i) | message =~ "(?i)error" | Находит error, ERROR или другие варианты с учетом регистра. |
| Исключение значений, соответствующих шаблону регулярного выражения | !~ | message !~ "^DEBUG" | Исключает строки, начинающиеся с DEBUG. |
Используйте LIKE для простого сопоставления с подстановочными знаками. Используйте регулярные выражения, если шаблону требуются классы символов, повторения, альтернативы (например, error|failed), якоря или сопоставление без учета регистра.
Используйте LIKE
Оператор LIKE предназначен для простого сопоставления с подстановочными знаками в строковых значениях. Он поддерживает только следующие подстановочные знаки:
| Символ подстановки | Описание |
|---|---|
% | Соответствует нулю или большему количеству символов. |
_ | Соответствует ровно одному символу. |
Распространенные шаблоны LIKE
Используйте позиции % и _ для управления тем, где фиксированный текст появляется в найденной строке.
| Требование | Шаблон | Пример фильтра |
|---|---|---|
| Начинается с префикса | Prod% | filter = 'name LIKE "Prod%"' |
| Заканчивается суффиксом | %.json | filter = 'filename LIKE "%.json"' |
| Содержит подстроку | %vector% | filter = 'description LIKE "%vector%"' |
| Соответствует одному символу в фиксированной позиции | AB_% | filter = 'code LIKE "AB_%"' |
Поведение сопоставления LIKE
Используйте оператор « LIKE » для поиска префиксов, суффиксов, подстрок и одиночных символов в фиксированной позиции. Оператор « LIKE » не поддерживает классы символов ( [0-9]), альтернативы ( error|failed), количество повторений ( {4}), анкоры ( ^ или $) и флаги, игнорирующие регистр ( (?i)). Для таких шаблонов используйте регулярные выражения.
Используйте == для точного сравнения полных строк. Используйте LIKE только в тех случаях, когда фильтру требуется сопоставление с подстановочными знаками.
Экранирование подстановочных знаков в шаблоне LIKE
В шаблонах типа LIKE символ % соответствует нулю или большему количеству символов, а _ — ровно одному символу. Чтобы буквально сопоставить %, _ или \, следует экранировать символ обратной косой чертой (\):
name LIKE r"\%"соответствует буквальному значению%.name LIKE r"\_%"соответствует значениям, начинающимся с литерала_.name LIKE r"\\%"соответствует значениям, начинающимся с литерального обратного слеша.
Литералы необработанных строк, записанные в виде r"..." или r'...', сохраняют обратные косые черты в исходном виде в выражениях фильтров Milvus. Их рекомендуется использовать для шаблонов LIKE и регулярных выражений, содержащих обратные косые черты. Без необработанной строки обычные строковые литералы по-прежнему обрабатывают экранирующие последовательности перед вычислением шаблона, поэтому может потребоваться больше обратных косых черт.
Используйте регулярные выраженияCompatible with Milvus 3.0.x
Используйте фильтры на основе регулярных выражений, если шаблон требует таких возможностей регулярных выражений, как классы символов, повторения, альтернативы, якоря или сопоставление без учета регистра. Milvus применяет регулярное выражение RE2 к строковому значению.
Правая часть выражения =~ или !~ должна представлять собой строковый литерал.
| Оператор | Значение | Пример |
|---|---|---|
=~ | Соответствует значениям, удовлетворяющим шаблону регулярного выражения. | filter = 'message =~ "E[0-9]{4}"' |
!~ | Исключает значения, удовлетворяющие шаблону регулярного выражения. | filter = 'message !~ "^DEBUG"' |
Используйте литералы необработанных строк
Сырые строковые литералы рекомендуются для шаблонов регулярных выражений, содержащих обратные косые черты. В сырой строке, записанной в виде r"..." или r'...', обратные косые черты передаются механизму регулярных выражений дословно. Это позволяет избежать дополнительного экранирования, требуемого при использовании обычных строковых литералов.
Например:
filter = r'filename =~ r"\.json$"'
String filter = "filename =~ r\"\\.json$\"";
filter := `filename =~ r"\.json$"`
const filter = 'filename =~ r"\\.json$"';
filter='filename =~ r"\.json$"'
Это выражение находит строки, заканчивающиеся на .json, например report.json.
Без использования «сырой» строки в выражении фильтра Milvus обычные строковые литералы обрабатывают экранирующие последовательности до того, как шаблон регулярного выражения будет проанализирован. Поэтому экранированные символы литерала могут потребовать добавления дополнительных обратных косых черт в строке на языке хоста.
Распространённые шаблоны регулярных выражений
В приведенных ниже примерах используется распространённый синтаксис RE2 в выражениях фильтров Milvus. Полную информацию о синтаксисе регулярных выражений см. в справочнике по синтаксису RE2.
| Требование | Шаблон | Пример фильтра |
|---|---|---|
| Содержит буквенный текст | error | filter = 'message =~ "error"' |
| Начинается с префикса | ^ERR | filter = 'code =~ "^ERR"' |
| Заканчивается суффиксом | \.json$ | filter = 'filename =~ "\\.json$"' |
| Соответствует последовательности цифр | [0-9]+ | filter = 'message =~ "[0-9]+"' |
| Соответствует фиксированному количеству цифр | [0-9]{4} | filter = 'code =~ "[0-9]{4}"' |
| Соответствует домену электронной почты | @example\.com$ | filter = 'email =~ "@example\\.com$"' |
| Соответствует без учета регистра | (?i)error | filter = 'message =~ "(?i)error"' |
| Соответствует всей строке | ^prod-[0-9]+$ | filter = 'name =~ "^prod-[0-9]+$"' |
Чтобы найти одно из нескольких слов, используйте альтернативу с помощью |:
filter = 'message =~ "error|failed|timeout"'
String filter = "message =~ \"error|failed|timeout\"";
filter := `message =~ "error|failed|timeout"`
const filter = 'message =~ "error|failed|timeout"';
filter='message =~ "error|failed|timeout"'
При буквальном сопоставлении метасимволов регулярных выражений необходимо экранировать их в шаблоне регулярного выражения. Например, чтобы найти буквальную точку (\. в регулярном выражении), в исходной строке на Python, Java, Go или Node.js нужно написать \\.:
filter = 'email =~ "@gmail\\.com$"'
String filter = "email =~ \"@gmail\\.com$\"";
filter := `email =~ "@gmail\\.com$"`
const filter = 'email =~ "@gmail\\.com$"';
filter='email =~ "@gmail\\.com$"'
Примечание: Фильтры регулярных выражений Milvus следуют синтаксису RE2. Если шаблон регулярного выражения использует синтаксис, который не поддерживается RE2, или является недействительным по иным причинам, Milvus отклоняет выражение фильтра. Подробную информацию о метасимволах регулярных выражений, флагах и поведении при сопоставлении см. в справочнике по синтаксису RE2.
Поведение при сопоставлении
Сопоставление подстрок
Сопоставление по регулярным выражениям в Milvus использует семантику подстрок. Шаблон не обязательно должен совпадать со всем значением поля. Например, следующий фильтр сопоставляет как E1001, так и failed with E1001 after retry:
filter = 'message =~ "E[0-9]{4}"'
String filter = "message =~ \"E[0-9]{4}\"";
filter := `message =~ "E[0-9]{4}"`
const filter = 'message =~ "E[0-9]{4}"';
filter='message =~ "E[0-9]{4}"'
Чтобы сопоставить всё значение поля, используйте якоря ^ и $:
# Match only values that are exactly E followed by four digits
filter = 'code =~ "^E[0-9]{4}$"'
// Match only values that are exactly E followed by four digits
String filter = "code =~ \"^E[0-9]{4}$\"";
// Match only values that are exactly E followed by four digits
filter := `code =~ "^E[0-9]{4}$"`
// Match only values that are exactly E followed by four digits
const filter = 'code =~ "^E[0-9]{4}$"';
# Match only values that are exactly E followed by four digits
filter='code =~ "^E[0-9]{4}$"'
Поля VARCHAR, допускающие нулевые значения
Фильтры на основе регулярных выражений не сопоставляются с нулевыми значениями. Это относится как к =~, так и к !~. Если вы хотите исключить шаблон регулярного выражения, но сохранить нулевые значения, явно добавьте OR field IS NULL:
filter = 'message !~ "^DEBUG" OR message IS NULL'
String filter = "message !~ \"^DEBUG\" OR message IS NULL";
filter := `message !~ "^DEBUG" OR message IS NULL`
const filter = 'message !~ "^DEBUG" OR message IS NULL';
filter='message !~ "^DEBUG" OR message IS NULL'
JSON-пути
В случае JSON-путей фильтры регулярных выражений ведут себя по-разному, если путь отсутствует, имеет значение null или преобразуется в значение, не являющееся строкой:
| Фильтр | Включает отсутствующие/нулевые/нестроковые значения? | Примечания |
|---|---|---|
json_field["path"] =~ "pattern" | Нет | Соответствует только строковым значениям, удовлетворяющим шаблону регулярного выражения. |
json_field["path"] !~ "pattern" | Да | Возвращает сущности, у которых путь отсутствует, имеет значение null, не является строкой или представляет собой строку, не соответствующую шаблону регулярного выражения. |
Ускорение сопоставления шаблонов с помощью индексов
Milvus поддерживает несколько типов индексов для строковых полей, которые можно использовать вместе с фильтрами « LIKE » и фильтрами на основе регулярных выражений для полей типа « VARCHAR » или строковых путей JSON, таких как « NGRAM », « STL_SORT », « INVERTED » и « BITMAP ». Сопоставление по шаблонам может работать и без индекса, но индекс позволяет повысить производительность при работе с большими наборами данных.
Эффективность индекса зависит от выражения шаблона, от того, может ли Milvus извлекать фиксированные литеральные подстроки, а также от кардинальности и распределения целевого поля. Для шаблонов префиксного типа, таких как name LIKE "Prod%", могут быть более эффективны другие стратегии индексирования, чем для шаблонов инфиксного или суффиксного типа, таких как description LIKE "%vector%" или filename LIKE "%.json".
Используйте приведенную ниже таблицу в качестве отправной точки, а затем проведите тестирование на вашей собственной рабочей нагрузке:
| Шаблон или характеристика данных | Рекомендуемый индекс | Примечания |
|---|---|---|
Содержит фиксированные литеральные подстроки, например message =~ "error.*timeout" или message LIKE "%database%" | NGRAM | Помогает в тех случаях, когда Milvus может извлечь значимые литеральные подстроки из шаблона. Подробности см. в разделе NGRAM. |
| Префиксные, точные или фильтры строк, основанные на равенстве, особенно для полей с низкой или умеренной кардинальностью | STL_SORT, « INVERTED » или BITMAP | Могут быть более эффективны, если в поле встречаются повторяющиеся значения или если фильтр близок к точному сопоставлению. Подробности см. в разделах STL_SORT, INVERTED и BITMAP. |
| Шаблоны регулярных выражений без фиксированных литералов или шаблоны, в которых преобладают классы символов, короткие токены или подстановочные знаки | Проведите тестирование производительности, прежде чем полагаться на ускорение за счёт индекса | Эти шаблоны могут обеспечивать ограниченную селективность индекса и привести к переходу на более широкое сканирование. |