milvus-logo
LFAI
Home
  • Benutzerhandbuch

Dynamisches Feld aktivieren

Auf dieser Seite wird erklärt, wie Sie das dynamische Feld in einer Sammlung für die flexible Dateneinfügung und -abfrage verwenden können.

Übersicht

Milvus ermöglicht es Ihnen, das Schema einer Sammlung zu definieren, indem Sie den Namen und den Datentyp jedes spezifischen Feldes festlegen, so dass Sie Indizes in diesen Feldern für eine verbesserte Suchleistung erstellen können.

Sobald ein Feld definiert ist, müssen Sie dieses Feld einbeziehen, wenn Sie Daten einfügen. Was aber, wenn einige Felder nicht immer in allen Ihren Dateneinträgen vorhanden sind? An dieser Stelle kommt das dynamische Feld ins Spiel.

Das dynamische Feld in einer Sammlung ist ein reserviertes JSON-Feld namens $meta. Es kann nicht schema-definierte Felder und ihre Werte als Schlüssel-Wert-Paare enthalten. Mit dem dynamischen Feld können Sie sowohl schema-definierte Felder als auch nicht-schema-definierte Felder suchen und abfragen, die sie möglicherweise enthalten.

Dynamisches Feld aktivieren

Bei der Definition eines Schemas für eine Sammlung können Sie enable_dynamic_field auf True setzen, um das reservierte dynamische Feld zu aktivieren. Dies bedeutet, dass alle nicht schemadefinierten Felder und deren Werte, die später eingefügt werden, als Schlüssel-Wert-Paare im reservierten dynamischen Feld gespeichert werden.

Das folgende Snippet erstellt eine Sammlung mit zwei schema-definierten Feldern, nämlich id und vector, und aktiviert das dynamische Feld.

Weitere Informationen über Parameter finden Sie unter create_collection() in der SDK-Referenz.

Weitere Informationen zu Parametern finden Sie unter createCollection() in der SDK-Referenz.

Weitere Informationen zu Parametern finden Sie unter createCollection() in der SDK-Referenz.

import random, time
from pymilvus import connections, MilvusClient, DataType

SERVER_ADDR = "http://localhost:19530"

# 1. Set up a Milvus client
client = MilvusClient(
    uri=SERVER_ADDR
)

# 2. Create a collection
schema = MilvusClient.create_schema(
    auto_id=False,
    enable_dynamic_field=True,
)

schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=5)

index_params = MilvusClient.prepare_index_params()

index_params.add_index(
    field_name="id",
    index_type="STL_SORT"
)

index_params.add_index(
    field_name="vector",
    index_type="IVF_FLAT",
    metric_type="L2",
    params={"nlist": 1024}
)

client.create_collection(
    collection_name="test_collection",
    schema=schema,
    index_params=index_params
)

res = client.get_load_state(
    collection_name="test_collection"
)

print(res)

# Output
#
# {
#     "state": "<LoadState: Loaded>"
# }
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.*;
import io.milvus.v2.service.vector.request.*;
import io.milvus.v2.service.vector.request.data.*;
import io.milvus.v2.service.vector.response.*;

import java.util.*;

String CLUSTER_ENDPOINT = "http://localhost:19530";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
        .uri(CLUSTER_ENDPOINT)
        .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);

// 2. Create a collection in customized setup mode

// 2.1 Create schema
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.setEnableDynamicField(true);

// 2.2 Add fields to schema
schema.addField(AddFieldReq.builder().fieldName("id").dataType(DataType.Int64).isPrimaryKey(true).autoID(false).build());
schema.addField(AddFieldReq.builder().fieldName("vector").dataType(DataType.FloatVector).dimension(5).build());

// 2.3 Prepare index parameters
IndexParam indexParamForIdField = IndexParam.builder()
        .fieldName("id")
        .indexType(IndexParam.IndexType.STL_SORT)
        .build();

Map<String, Object> params = new HashMap<>();
params.put("nlist", 1024);
IndexParam indexParamForVectorField = IndexParam.builder()
        .fieldName("vector")
        .indexType(IndexParam.IndexType.IVF_FLAT)
        .metricType(IndexParam.MetricType.IP)
        .extraParams(params)
        .build();

List<IndexParam> indexParams = new ArrayList<>();
indexParams.add(indexParamForIdField);
indexParams.add(indexParamForVectorField);

// 2.4 Create a collection with schema and index parameters
CreateCollectionReq customizedSetupReq = CreateCollectionReq.builder()
        .collectionName("customized_setup")
        .collectionSchema(schema)
        .indexParams(indexParams)
        .build();

client.createCollection(customizedSetupReq);

Thread.sleep(5000);

// 2.5 Get load state of the collection
GetLoadStateReq customSetupLoadStateReq1 = GetLoadStateReq.builder()
        .collectionName("customized_setup")
        .build();

boolean res = client.getLoadState(customSetupLoadStateReq1);

System.out.println(res);

// Output:
// true
const { MilvusClient, DataType, sleep } = require("@zilliz/milvus2-sdk-node")

const address = "http://localhost:19530"

async function main() {
// 1. Set up a Milvus Client
client = new MilvusClient({address}); 

// 2. Create a collection
// 2.1 Define fields
const fields = [
    {
        name: "id",
        data_type: DataType.Int64,
        is_primary_key: true,
        auto_id: false
    },
    {
        name: "vector",
        data_type: DataType.FloatVector,
        dim: 5
    },
]

// 2.2 Prepare index parameters
const index_params = [{
    field_name: "id",
    index_type: "STL_SORT"
},{
    field_name: "vector",
    index_type: "IVF_FLAT",
    metric_type: "IP",
    params: { nlist: 1024}
}]

// 2.3 Create a collection with fields and index parameters
res = await client.createCollection({
    collection_name: "test_collection",
    fields: fields, 
    index_params: index_params,
    enable_dynamic_field: true
})

console.log(res.error_code)

// Output
// 
// Success
// 

res = await client.getLoadState({
    collection_name: "test_collection",
})  

console.log(res.state)

// Output
// 
// LoadStateLoaded
// 

Einfügen dynamischer Daten

Sobald die Sammlung erstellt ist, können Sie mit dem Einfügen von Daten, einschließlich der dynamischen Daten, in die Sammlung beginnen.

Daten vorbereiten

In diesem Abschnitt müssen Sie einige zufällig generierte Daten für das spätere Einfügen vorbereiten.

colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
data = []

for i in range(1000):
    current_color = random.choice(colors)
    current_tag = random.randint(1000, 9999)
    data.append({
        "id": i,
        "vector": [ random.uniform(-1, 1) for _ in range(5) ],
        "color": current_color,
        "tag": current_tag,
        "color_tag": f"{current_color}_{str(current_tag)}"
    })

print(data[0])
List<String> colors = Arrays.asList("green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey");
List<JsonObject> data = new ArrayList<>();
Gson gson = new Gson();
Random rand = new Random();
for (int i=0; i<1000; i++) {
    String current_color = colors.get(rand.nextInt(colors.size()-1));
    int current_tag = rand.nextInt(8999) + 1000;
    JsonObject row = new JsonObject();
    row.addProperty("id", (long) i);
    row.add("vector", gson.toJsonTree(Arrays.asList(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat())));
    row.addProperty("color", current_color);
    row.addProperty("tag", current_tag);
    row.addProperty("color_tag", current_color + "_" + (rand.nextInt(8999) + 1000));
    data.add(row);
}

System.out.println(data.get(0).toString());
const colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
var data = []

for (let i = 0; i < 1000; i++) {
    const current_color = colors[Math.floor(Math.random() * colors.length)]
    const current_tag = Math.floor(Math.random() * 8999 + 1000)
    data.push({
        id: i,
        vector: [Math.random(), Math.random(), Math.random(), Math.random(), Math.random()],
        color: current_color,
        tag: current_tag,
        color_tag: `${current_color}_${current_tag}`
    })
}

console.log(data[0])

Sie können die Struktur der generierten Daten sehen, indem Sie den ersten Eintrag überprüfen.

{
    id: 0,
    vector: [
        0.1275656405044483,
        0.47417858592773277,
        0.13858264437643286,
        0.2390904907020377,
        0.8447862593689635
    ],
    color: 'blue',
    tag: 2064,
    color_tag: 'blue_2064'
}

Daten einfügen

Anschließend können Sie die Daten sicher in die Sammlung einfügen.

Weitere Informationen zu Parametern finden Sie unter insert() in der SDK-Referenz.

Weitere Informationen zu den Parametern finden Sie unter insert() in der SDK-Referenz.

Weitere Informationen zu Parametern finden Sie unter insert() in der SDK-Referenz.

res = client.insert(
    collection_name="test_collection",
    data=data,
)

print(res)

# Output
#
# {
#     "insert_count": 1000,
#     "ids": [
#         0,
#         1,
#         2,
#         3,
#         4,
#         5,
#         6,
#         7,
#         8,
#         9,
#         "(990 more items hidden)"
#     ]
# }

time.sleep(5)
// 3.1 Insert data into the collection
InsertReq insertReq = InsertReq.builder()
        .collectionName("customized_setup")
        .data(data)
        .build();

InsertResp insertResp = client.insert(insertReq);

System.out.println(insertResp.getInsertCnt());

// Output:
// 1000

Thread.sleep(5000);
res = await client.insert({
    collection_name: "test_collection",
    data: data,
})

console.log(res.insert_cnt)

// Output
// 
// 1000
// 

await sleep(5000)

Suche mit dynamischen Feldern

Wenn Sie die Sammlung mit aktiviertem dynamischen Feld erstellt und nicht schema-definierte Felder eingefügt haben, können Sie diese Felder wie folgt im Filterausdruck einer Suche oder Abfrage verwenden.

Weitere Informationen über Parameter finden Sie unter search() in der SDK-Referenz.

Weitere Informationen zu Parametern finden Sie unter search() in der SDK-Referenz.

Weitere Informationen zu Parametern finden Sie unter search() in der SDK-Referenz.

# 4. Search with dynamic fields
query_vectors = [[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]]

res = client.search(
    collection_name="test_collection",
    data=query_vectors,
    filter="color in [\"red\", \"green\"]",
    search_params={"metric_type": "L2", "params": {"nprobe": 10}},
    limit=3
)

print(res)

# Output
#
# [
#     [
#         {
#             "id": 863,
#             "distance": 0.188413605093956,
#             "entity": {
#                 "id": 863,
#                 "color_tag": "red_2371"
#             }
#         },
#         {
#             "id": 799,
#             "distance": 0.29188022017478943,
#             "entity": {
#                 "id": 799,
#                 "color_tag": "red_2235"
#             }
#         },
#         {
#             "id": 564,
#             "distance": 0.3492690920829773,
#             "entity": {
#                 "id": 564,
#                 "color_tag": "red_9186"
#             }
#         }
#     ]
# ]
// 4. Search with non-schema-defined fields
List<BaseVector> queryVectors = Collections.singletonList(new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f}));

SearchReq searchReq = SearchReq.builder()
        .collectionName("customized_setup")
        .data(queryVectors)
        .filter("$meta[\"color\"] in [\"red\", \"green\"]")
        .outputFields(Arrays.asList("id", "color_tag"))
        .topK(3)
        .build();

SearchResp searchResp = client.search(searchReq);

List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
    System.out.println("TopK results:");
    for (SearchResp.SearchResult result : results) {
        System.out.println(result);
    }
}

// Output:
// SearchResp.SearchResult(entity={color_tag=green_2205, id=556}, score=1.134007, id=556)
// SearchResp.SearchResult(entity={color_tag=red_2786, id=310}, score=0.9072295, id=310)
// SearchResp.SearchResult(entity={color_tag=red_9493, id=215}, score=0.8819287, id=215)
// 4. Search with non-schema-defined fields
const query_vectors = [[0.1, 0.2, 0.3, 0.4, 0.5]]

res = await client.search({
    collection_name: "test_collection",
    data: query_vectors,
    filter: "color in [\"red\", \"green\"]",
    output_fields: ["color_tag"],
    limit: 3
})

console.log(res.results)

// Output
// 
// [
//   { score: 1.2284551858901978, id: '301', color_tag: 'red_1270' },
//   { score: 1.2195171117782593, id: '205', color_tag: 'red_2780' },
//   { score: 1.2055039405822754, id: '487', color_tag: 'red_6653' }
// ]
// 

Wiederholungen

Es ist erwähnenswert, dass color, tag und color_tag bei der Definition des Auflistungsschemas nicht vorhanden sind, aber Sie können sie als schema-definierte Felder verwenden, wenn Sie Suchen und Abfragen durchführen.

Wenn der Name eines nicht schema-definierten Feldes andere Zeichen als Ziffern, Buchstaben und Unterstriche enthält, z. B. Pluszeichen (+), Sternchen (*) oder Dollarzeichen ($), müssen Sie den Schlüssel in $meta[] einschließen, wie im folgenden Codeschnipsel gezeigt, wenn Sie ihn in einem booleschen Ausdruck verwenden oder ihn in die Ausgabefelder einschließen.

... 
filter='$meta["$key"] in ["a", "b", "c"]', 
output_fields='$meta["$key"]'  
...

Übersetzt vonDeepL

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

War diese Seite hilfreich?