Сопоставление текстов
Текстовое соответствие в Milvus позволяет точно находить документы по определенным терминам. Эта функция в основном используется для фильтрации поиска по определенным условиям и может включать скалярную фильтрацию для уточнения результатов запроса, позволяя искать сходство в векторах, которые соответствуют скалярным критериям.
Текстовое совпадение нацелено на поиск точных вхождений терминов запроса, без оценки релевантности сопоставленных документов. Если вы хотите получить наиболее релевантные документы, основанные на семантическом значении и важности терминов запроса, мы рекомендуем вам использовать полнотекстовый поиск.
Обзор
Milvus интегрирует Tantivy для работы с инвертированным индексом и текстовым поиском по терминам. Для каждой текстовой записи Milvus индексирует ее в соответствии с процедурой.
Анализатор: Анализатор обрабатывает входной текст, разбивая его на отдельные слова, или лексемы, а затем применяя фильтры по мере необходимости. Это позволяет Milvus построить индекс на основе этих лексем.
Индексирование: После анализа текста Milvus создает инвертированный индекс, который сопоставляет каждую уникальную лексему с содержащими ее документами.
Когда пользователь выполняет поиск по тексту, инвертированный индекс используется для быстрого извлечения всех документов, содержащих эти термины. Это гораздо быстрее, чем сканирование каждого документа по отдельности.
Совпадение текста
Включить текстовое соответствие
Текстовое совпадение работает с типом поля VARCHAR
, который по сути является строковым типом данных в Milvus. Чтобы включить текстовое соответствие, установите значения enable_analyzer
и enable_match
на True
, а затем при определении схемы коллекции настройте анализатор для текстового анализа.
Установите enable_analyzer
и enable_match
.
Чтобы включить текстовое соответствие для определенного поля VARCHAR
, при определении схемы поля установите параметры enable_analyzer
и enable_match
в значение True
. Это дает Milvus указание токенизировать текст и создать инвертированный индекс для указанного поля, обеспечивая быстрое и эффективное текстовое соответствие.
from pymilvus import MilvusClient, DataType
schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)
schema.add_field(
field_name='text',
datatype=DataType.VARCHAR,
max_length=1000,
enable_analyzer=True, # Whether to enable text analysis for this field
enable_match=True # Whether to enable text match
)
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder()
.enableDynamicField(false)
.build();
schema.addField(AddFieldReq.builder()
.fieldName("text")
.dataType(DataType.VarChar)
.maxLength(1000)
.enableAnalyzer(true)
.enableMatch(true)
.build());
const schema = [
{
name: "id",
data_type: DataType.Int64,
is_primary_key: true,
},
{
name: "text",
data_type: "VarChar",
enable_analyzer: true,
enable_match: true,
max_length: 1000,
},
{
name: "sparse",
data_type: DataType.SparseFloatVector,
},
];
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "text",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 1000,
"enable_analyzer": true,
"enable_match": true
}
},
{
"fieldName": "sparse",
"dataType": "SparseFloatVector"
}
]
}'
Необязательно: Настройка анализатора
Производительность и точность подбора текста зависят от выбранного анализатора. Различные анализаторы приспособлены к различным языкам и структурам текста, поэтому выбор правильного анализатора может существенно повлиять на результаты поиска для конкретного случая использования.
По умолчанию в Milvus используется анализатор standard
, который выполняет токенизацию текста на основе пробелов и пунктуации, удаляет лексемы длиной более 40 символов и преобразует текст в строчные буквы. Для применения этой настройки по умолчанию не требуется никаких дополнительных параметров. Дополнительные сведения см. в разделе Стандартный.
В случаях, когда требуется другой анализатор, его можно настроить с помощью параметра analyzer_params
. Например, чтобы применить анализатор english
для обработки английского текста.
analyzer_params={
"type": "english"
}
schema.add_field(
field_name='text',
datatype=DataType.VARCHAR,
max_length=200,
enable_analyzer=True,
analyzer_params=analyzer_params,
enable_match=True,
)
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("type", "english");
schema.addField(AddFieldReq.builder()
.fieldName("text")
.dataType(DataType.VarChar)
.maxLength(200)
.enableAnalyzer(true)
.analyzerParams(analyzerParams)
.enableMatch(true)
.build());
const schema = [
{
name: "id",
data_type: DataType.Int64,
is_primary_key: true,
},
{
name: "text",
data_type: "VarChar",
enable_analyzer: true,
enable_match: true,
max_length: 1000,
analyzer_params: { type: 'english' },
},
{
name: "sparse",
data_type: DataType.SparseFloatVector,
},
];
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "text",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 200,
"enable_analyzer": true,
"enable_match": true,
"analyzer_params": {"type": "english"}
}
},
{
"fieldName": "my_vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": "5"
}
}
]
}'
Milvus также предоставляет различные другие анализаторы, подходящие для разных языков и сценариев. Для получения более подробной информации обратитесь к разделу Обзор.
Использование текстового соответствия
После того как вы включили текстовое соответствие для поля VARCHAR в схеме коллекции, вы можете выполнять текстовое соответствие с помощью выражения TEXT_MATCH
.
Синтаксис выражения TEXT_MATCH
Выражение TEXT_MATCH
используется для указания поля и условий для поиска. Его синтаксис выглядит следующим образом.
TEXT_MATCH(field_name, text)
field_name
: : Имя поля VARCHAR для поиска.text
: Термины для поиска. Несколько терминов могут быть разделены пробелами или другими соответствующими разделителями в зависимости от языка и настроенного анализатора.
По умолчанию TEXT_MATCH
использует логику поиска "ИЛИ", то есть возвращает документы, содержащие любой из указанных терминов. Например, для поиска документов, содержащих термин machine
или deep
в поле text
, используйте следующее выражение.
filter = "TEXT_MATCH(text, 'machine deep')"
String filter = "TEXT_MATCH(text, 'machine deep')";
const filter = "TEXT_MATCH(text, 'machine deep')";
export filter="\"TEXT_MATCH(text, 'machine deep')\""
Вы также можете объединить несколько выражений TEXT_MATCH
с помощью логических операторов для выполнения AND-сопоставления.
Для поиска документов, содержащих
machine
иdeep
в полеtext
, используйте следующее выражение.filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')"
String filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')";
const filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')"
export filter="\"TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')\""
Для поиска документов, содержащих
machine
иlearning
, но не содержащихdeep
в полеtext
, используйте следующие выражения:filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')"
String filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')";
const filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')";
export filter="\"not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')\""
Поиск с помощью текстового соответствия
Текстовое совпадение можно использовать в сочетании с поиском по векторному сходству, чтобы сузить область поиска и повысить его производительность. Фильтрация коллекции с помощью текстового соответствия перед векторным поиском по сходству позволяет сократить количество документов, в которых необходимо выполнить поиск, что приводит к сокращению времени выполнения запроса.
В этом примере выражение filter
фильтрует результаты поиска, чтобы включить только документы, соответствующие указанному термину keyword1
или keyword2
. Затем векторный поиск сходства выполняется для этого отфильтрованного подмножества документов.
# Match entities with `keyword1` or `keyword2`
filter = "TEXT_MATCH(text, 'keyword1 keyword2')"
# Assuming 'embeddings' is the vector field and 'text' is the VARCHAR field
result = MilvusClient.search(
collection_name="YOUR_COLLECTION_NAME", # Your collection name
anns_field="embeddings", # Vector field name
data=[query_vector], # Query vector
filter=filter,
search_params={"params": {"nprobe": 10}},
limit=10, # Max. number of results to return
output_fields=["id", "text"] # Fields to return
)
String filter = "TEXT_MATCH(text, 'keyword1 keyword2')";
SearchResp searchResp = client.search(SearchReq.builder()
.collectionName("YOUR_COLLECTION_NAME")
.annsField("embeddings")
.data(Collections.singletonList(queryVector)))
.filter(filter)
.topK(10)
.outputFields(Arrays.asList("id", "text"))
.build());
// Match entities with `keyword1` or `keyword2`
const filter = "TEXT_MATCH(text, 'keyword1 keyword2')";
// Assuming 'embeddings' is the vector field and 'text' is the VARCHAR field
const result = await client.search(
collection_name: "YOUR_COLLECTION_NAME", // Your collection name
anns_field: "embeddings", // Vector field name
data: [query_vector], // Query vector
filter: filter,
params: {"nprobe": 10},
limit: 10, // Max. number of results to return
output_fields: ["id", "text"] //Fields to return
);
export filter="\"TEXT_MATCH(text, 'keyword1 keyword2')\""
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "demo2",
"annsField": "my_vector",
"data": [[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104]],
"filter": '"$filter"',
"searchParams": {
"params": {
"nprobe": 10
}
},
"limit": 3,
"outputFields": ["text","id"]
}'
Запрос с текстовым совпадением
Текстовое соответствие также можно использовать для скалярной фильтрации в запросах. Указав выражение TEXT_MATCH
в параметре expr
метода query()
, вы можете получить документы, соответствующие заданным условиям.
В приведенном ниже примере извлекаются документы, в которых поле text
содержит термины keyword1
и keyword2
.
# Match entities with both `keyword1` and `keyword2`
filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')"
result = MilvusClient.query(
collection_name="YOUR_COLLECTION_NAME",
filter=filter,
output_fields=["id", "text"]
)
String filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')";
QueryResp queryResp = client.query(QueryReq.builder()
.collectionName("YOUR_COLLECTION_NAME")
.filter(filter)
.outputFields(Arrays.asList("id", "text"))
.build()
);
// Match entities with both `keyword1` and `keyword2`
const filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')";
const result = await client.query(
collection_name: "YOUR_COLLECTION_NAME",
filter: filter,
output_fields: ["id", "text"]
)
export filter="\"TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')\""
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" \
-d '{
"collectionName": "demo2",
"filter": '"$filter"',
"outputFields": ["id", "text"]
}'
Соображения
Включение текстового соответствия для поля приводит к созданию инвертированного индекса, который потребляет ресурсы хранилища. Учитывайте влияние на хранение данных, когда решите включить эту функцию, поскольку оно зависит от размера текста, уникальных лексем и используемого анализатора.
После определения анализатора в схеме его настройки становятся постоянными для данной коллекции. Если вы решите, что другой анализатор будет лучше соответствовать вашим потребностям, вы можете удалить существующую коллекцию и создать новую с нужной конфигурацией анализатора.
Правила экранирования в выражениях
filter
:- Символы, заключенные в двойные или одинарные кавычки в выражениях, интерпретируются как строковые константы. Если строковая константа включает в себя управляющие символы, то они должны быть представлены с помощью управляющей последовательности. Например, используйте
\\
для обозначения\
,\\t
для обозначения табуляции\t
, и\\n
для обозначения новой строки. - Если строковая константа заключена в одинарные кавычки, то одинарная кавычка внутри константы должна быть представлена как
\\'
, а двойная кавычка может быть представлена как"
или\\"
. Пример:'It\\'s milvus'
. - Если строковая константа заключена в двойные кавычки, то двойная кавычка внутри константы должна быть представлена как
\\"
, а одинарная кавычка может быть представлена как'
или\\'
. Пример:"He said \\"Hi\\""
.
- Символы, заключенные в двойные или одинарные кавычки в выражениях, интерпретируются как строковые константы. Если строковая константа включает в себя управляющие символы, то они должны быть представлены с помощью управляющей последовательности. Например, используйте