文字列フィールド
Milvusでは、VARCHAR
は文字列型データを格納するためのデータ型で、可変長の文字列を格納するのに適しています。シングルバイト文字とマルチバイト文字の両方の文字列を格納することができ、最大長は60,535文字までです。VARCHAR
フィールドを定義する際には、最大長パラメータmax_length
も指定する必要がある。VARCHAR
文字列型は、テキスト・データを格納・管理する効率的で柔軟な方法を提供し、さまざまな長さの文字列を扱うアプリケーションに最適です。
VARCHAR フィールドの追加
milvusで文字列データを使用するには、コレクション作成時にVARCHAR
フィールドを定義します。このプロセスには以下が含まれます。
datatype
をサポートされる文字列データ型、すなわちVARCHAR
に設定する。max_length
パラメータを使用して、文字列タイプの最大長を指定します(60,535 文字を超えることはできません)。
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri="http://localhost:19530")
# define schema
schema = client.create_schema(
auto_id=False,
enable_dynamic_fields=True,
)
schema.add_field(field_name="varchar_field1", datatype=DataType.VARCHAR, max_length=100)
schema.add_field(field_name="varchar_field2", datatype=DataType.VARCHAR, max_length=200)
schema.add_field(field_name="pk", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=3)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.build());
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.setEnableDynamicField(true);
schema.addField(AddFieldReq.builder()
.fieldName("varchar_field1")
.dataType(DataType.VarChar)
.maxLength(100)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("varchar_field2")
.dataType(DataType.VarChar)
.maxLength(200)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("pk")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("embedding")
.dataType(DataType.FloatVector)
.dimension(3)
.build());
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const schema = [
{
name: "metadata",
data_type: DataType.JSON,
},
{
name: "pk",
data_type: DataType.Int64,
is_primary_key: true,
},
{
name: "varchar_field2",
data_type: DataType.VarChar,
max_length: 200,
},
{
name: "varchar_field1",
data_type: DataType.VarChar,
max_length: 100,
},
];
export varcharField1='{
"fieldName": "varchar_field1",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 100
}
}'
export varcharField2='{
"fieldName": "varchar_field2",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 200
}
}'
export primaryField='{
"fieldName": "pk",
"dataType": "Int64",
"isPrimary": true
}'
export vectorField='{
"fieldName": "embedding",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": 3
}
}'
export schema="{
\"autoID\": false,
\"fields\": [
$varcharField1,
$varcharField2,
$primaryField,
$vectorField
]
}"
この例では、varchar_field1
とvarchar_field2
という2つのVARCHAR
フィールドを追加し、それぞれ最大長を100文字と200文字に設定しています。max_length
、過剰なスペース割り当てを避けながら最長データに対応できるように、データの特性に基づいて設定することを推奨します。さらに、プライマリ・フィールドpk
とベクトル・フィールドembedding
を追加した。
プライマリフィールドとベクトルフィールドは、コレクションを作成するときに必須です。プライマリフィールドは各エンティティを一意に識別し、ベクトルフィールドは類似性検索に重要である。詳細はPrimary Field & AutoID,Dense Vector,Binary Vector,Sparse Vector を参照。
インデックスパラメータの設定
VARCHAR
フィールドにインデックス・パラメータを設定することはオプションですが、検索効率を大幅に向上させることができます。
以下の例では、varchar_field1
にAUTOINDEX
を作成しています。つまり、milvusはデータ型に基づいて適切なインデックスを自動的に作成します。詳細については、AUTOINDEXを参照してください。
index_params = client.prepare_index_params()
index_params.add_index(
field_name="varchar_field1",
index_type="AUTOINDEX",
index_name="varchar_index"
)
import io.milvus.v2.common.IndexParam;
import java.util.*;
List<IndexParam> indexes = new ArrayList<>();
indexes.add(IndexParam.builder()
.fieldName("varchar_field1")
.indexName("varchar_index")
.indexType(IndexParam.IndexType.AUTOINDEX)
.build());
const indexParams = [{
index_name: 'varchar_index',
field_name: 'varchar_field1',
index_type: IndexType.AUTOINDEX,
)];
export indexParams='[
{
"fieldName": "varchar_field1",
"indexName": "varchar_index",
"indexType": "AUTOINDEX"
}
]'
AUTOINDEX
以外にも、INVERTED
やBITMAP
などのスカラー・インデックス・タイプを指定することができます。サポートされているインデックス・タイプについては、スカラー・インデックスを参照。
さらに、コレクションを作成する前に、ベクトル・フィールドのインデックスを作成する必要があります。この例では、AUTOINDEX
を使用して、ベクトル・インデックスの設定を簡素化しています。
# Add vector index
index_params.add_index(
field_name="embedding",
index_type="AUTOINDEX", # Use automatic indexing to simplify complex index settings
metric_type="COSINE" # Specify similarity metric type, options include L2, COSINE, or IP
)
indexes.add(IndexParam.builder()
.fieldName("embedding")
.indexType(IndexParam.IndexType.AUTOINDEX)
.metricType(IndexParam.MetricType.COSINE)
.build());
indexParams.push({
index_name: 'embedding_index',
field_name: 'embedding',
metric_type: MetricType.COSINE,
index_type: IndexType.AUTOINDEX,
});
export indexParams='[
{
"fieldName": "varchar_field1",
"indexName": "varchar_index",
"indexType": "AUTOINDEX"
},
{
"fieldName": "embedding",
"metricType": "COSINE",
"indexType": "AUTOINDEX"
}
]'
コレクションの作成
スキーマとインデックスが定義されたら、文字列フィールドを含むコレクションを作成できます。
# Create Collection
client.create_collection(
collection_name="your_collection_name",
schema=schema,
index_params=index_params
)
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("my_varchar_collection")
.collectionSchema(schema)
.indexParams(indexes)
.build();
client.createCollection(requestCreate);
client.create_collection({
collection_name: "my_varchar_collection",
schema: schema,
index_params: index_params
})
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
\"collectionName\": \"my_varchar_collection\",
\"schema\": $schema,
\"indexParams\": $indexParams
}"
## {"code":0,"data":{}}
データの挿入
コレクションを作成したら、文字列フィールドを含むデータを挿入できます。
data = [
{"varchar_field1": "Product A", "varchar_field2": "High quality product", "pk": 1, "embedding": [0.1, 0.2, 0.3]},
{"varchar_field1": "Product B", "varchar_field2": "Affordable price", "pk": 2, "embedding": [0.4, 0.5, 0.6]},
{"varchar_field1": "Product C", "varchar_field2": "Best seller", "pk": 3, "embedding": [0.7, 0.8, 0.9]},
]
client.insert(
collection_name="my_varchar_collection",
data=data
)
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp;
List<JsonObject> rows = new ArrayList<>();
Gson gson = new Gson();
rows.add(gson.fromJson("{\"varchar_field1\": \"Product A\", \"varchar_field2\": \"High quality product\", \"pk\": 1, \"embedding\": [0.1, 0.2, 0.3]}", JsonObject.class));
rows.add(gson.fromJson("{\"varchar_field1\": \"Product B\", \"varchar_field2\": \"Affordable price\", \"pk\": 2, \"embedding\": [0.4, 0.5, 0.6]}", JsonObject.class));
rows.add(gson.fromJson("{\"varchar_field1\": \"Product C\", \"varchar_field2\": \"Best seller\", \"pk\": 3, \"embedding\": [0.7, 0.8, 0.9]}", JsonObject.class));
InsertResp insertR = client.insert(InsertReq.builder()
.collectionName("my_varchar_collection")
.data(rows)
.build());
const data = [
{
varchar_field1: "Product A",
varchar_field2: "High quality product",
pk: 1,
embedding: [0.1, 0.2, 0.3],
},
{
varchar_field1: "Product B",
varchar_field2: "Affordable price",
pk: 2,
embedding: [0.4, 0.5, 0.6],
},
{
varchar_field1: "Product C",
varchar_field2: "Best seller",
pk: 3,
embedding: [0.7, 0.8, 0.9],
},
];
client.insert({
collection_name: "my_sparse_collection",
data: data,
});
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"data": [
{"varchar_field1": "Product A", "varchar_field2": "High quality product", "pk": 1, "embedding": [0.1, 0.2, 0.3]},
{"varchar_field1": "Product B", "varchar_field2": "Affordable price", "pk": 2, "embedding": [0.4, 0.5, 0.6]},
{"varchar_field1": "Product C", "varchar_field2": "Best seller", "pk": 3, "embedding": [0.7, 0.8, 0.9]}
],
"collectionName": "my_varchar_collection"
}'
## {"code":0,"cost":0,"data":{"insertCount":3,"insertIds":[1,2,3]}}
この例では、VARCHAR
フィールド(varchar_field1
とvarchar_field2
)、主フィールド(pk
)、ベクトル表現(embedding
)を含むデータを挿入します。挿入されたデータがスキーマで定義されたフィールドと一致していることを確認するために、挿入エラーを避けるために事前にデータ型をチェックすることをお勧めします。
スキーマ定義時にenable_dynamic_fields=True
を設定すると、milvusでは事前に定義されていない文字列フィールドを挿入することができます。ただし、この場合、クエリや管理の複雑さが増し、パフォーマンスに影響を与える可能性があることに留意してください。詳細はDynamic Fieldを参照してください。
検索とクエリ
文字列フィールドを追加すると、検索やクエリ操作のフィルタリングに使用でき、より正確な検索結果を得ることができます。
フィルタ・クエリ
文字列フィールドを追加すると、クエリでこれらのフィールドを使用して結果をフィルタリングできます。たとえば、varchar_field1
が"Product A"
と等しいエンティティをすべてクエリできます。
filter = 'varchar_field1 == "Product A"'
res = client.query(
collection_name="my_varchar_collection",
filter=filter,
output_fields=["varchar_field1", "varchar_field2"]
)
print(res)
# Output
# data: ["{'varchar_field1': 'Product A', 'varchar_field2': 'High quality product', 'pk': 1}"]
import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;
String filter = "varchar_field1 == \"Product A\"";
QueryResp resp = client.query(QueryReq.builder()
.collectionName("my_varchar_collection")
.filter(filter)
.outputFields(Arrays.asList("varchar_field1", "varchar_field2"))
.build());
System.out.println(resp.getQueryResults());
// Output
//
// [QueryResp.QueryResult(entity={varchar_field1=Product A, varchar_field2=High quality product, pk=1})]
client.query({
collection_name: 'my_varchar_collection',
filter: 'varchar_field1 == "Product A"',
output_fields: ['varchar_field1', 'varchar_field2']
});
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_varchar_collection",
"filter": "varchar_field1 == \"Product A\"",
"outputFields": ["varchar_field1", "varchar_field2"]
}'
## {"code":0,"cost":0,"data":[{"pk":1,"varchar_field1":"Product A","varchar_field2":"High quality product"}]}
このクエリ式は、一致するすべてのエンティティを返し、それらのvarchar_field1
フィールドとvarchar_field2
フィールドを出力します。フィルタ・クエリの詳細については、「メタデータ・フィルタリング」を参照してください。
文字列フィルタリングによるベクトル検索
基本的なスカラー・フィールド・フィルタリングに加えて、ベクトル類似性検索をスカラー・フィールド・フィルタリングと組み合わせることができます。例えば、次のコードはベクトル検索にスカラー・フィールド・フィルターを追加する方法を示している。
filter = 'varchar_field1 == "Product A"'
res = client.search(
collection_name="my_varchar_collection",
data=[[0.3, -0.6, 0.1]],
limit=5,
search_params={"params": {"nprobe": 10}},
output_fields=["varchar_field1", "varchar_field2"],
filter=filter
)
print(res)
# Output
# data: ["[{'id': 1, 'distance': -0.06000000238418579, 'entity': {'varchar_field1': 'Product A', 'varchar_field2': 'High quality product'}}]"]
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
String filter = "varchar_field1 == \"Product A\"";
SearchResp resp = client.search(SearchReq.builder()
.collectionName("my_varchar_collection")
.annsField("embedding")
.data(Collections.singletonList(new FloatVec(new float[]{0.3f, -0.6f, 0.1f})))
.topK(5)
.outputFields(Arrays.asList("varchar_field1", "varchar_field2"))
.filter(filter)
.build());
System.out.println(resp.getSearchResults());
// Output
//
// [[SearchResp.SearchResult(entity={varchar_field1=Product A, varchar_field2=High quality product}, score=-0.2364331, id=1)]]
client.search({
collection_name: 'my_varchar_collection',
data: [0.3, -0.6, 0.1],
limit: 5,
output_fields: ['varchar_field1', 'varchar_field2'],
filter: 'varchar_field1 == "Product A"'
params: {
nprobe:10
}
});
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_varchar_collection",
"data": [
[0.3, -0.6, 0.1]
],
"limit": 5,
"searchParams":{
"params":{"nprobe":10}
},
"outputFields": ["varchar_field1", "varchar_field2"],
"filter": "varchar_field1 == \"Product A\""
}'
## {"code":0,"cost":0,"data":[{"distance":-0.2364331,"id":1,"varchar_field1":"Product A","varchar_field2":"High quality product"}]}
この例では、まずクエリー・ベクターを定義し、検索中にフィルター条件(varchar_field1 == "Product A"
)を追加する。これにより、検索結果がクエリー・ベクターに類似しているだけでなく、指定された文字列フィルター条件にも一致することが保証される。詳細については、メタデータのフィルタリングを参照してください。