Skip to content

Commit b56bfb5

Browse files
authored
Support AddFunctionField/DropCollectionField/DropFunctionField interfaces (#531)
Signed-off-by: yhmo <yihua.mo@zilliz.com>
1 parent a6d4979 commit b56bfb5

15 files changed

Lines changed: 983 additions & 123 deletions

examples/src/v2/add_field.cpp

Lines changed: 132 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -15,164 +15,173 @@
1515
// limitations under the License.
1616

1717
#include <iostream>
18+
#include <memory>
1819
#include <string>
19-
#include <thread>
20+
#include <vector>
2021

2122
#include "ExampleUtils.h"
2223
#include "milvus/MilvusClientV2.h"
2324

24-
int
25-
main(int argc, char* argv[]) {
26-
printf("Example start...\n");
27-
28-
auto client = milvus::MilvusClientV2::Create();
29-
30-
milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
31-
auto status = client->Connect(connect_param);
32-
util::CheckStatus("connect milvus server", status);
33-
34-
const std::string collection_name = "CPP_V2_ADD_FIELD";
35-
const std::string field_id = "pk";
36-
const std::string field_vector = "vector";
37-
const uint32_t dimension = 4;
38-
39-
// collection schema, drop and create collection
40-
milvus::CollectionSchemaPtr collection_schema = std::make_shared<milvus::CollectionSchema>();
41-
collection_schema->AddField({field_id, milvus::DataType::INT64, "", true, true});
25+
namespace {
26+
const std::string collection_name = "CPP_V2_ADD_FIELD";
27+
const std::string field_id = "id";
28+
const std::string field_vector = "vector";
29+
const std::string field_text = "text";
30+
const std::string field_sparse = "sparse";
31+
const std::string function_name = "bm25";
32+
const uint32_t dimension = 8;
33+
34+
void
35+
CreateCollection(milvus::MilvusClientV2Ptr& client) {
36+
auto collection_schema = std::make_shared<milvus::CollectionSchema>();
37+
collection_schema->AddField({field_id, milvus::DataType::INT64, "", true, false});
4238
collection_schema->AddField(
4339
milvus::FieldSchema(field_vector, milvus::DataType::FLOAT_VECTOR).WithDimension(dimension));
4440

45-
status = client->DropCollection(milvus::DropCollectionRequest().WithCollectionName(collection_name));
41+
auto status = client->DropCollection(milvus::DropCollectionRequest().WithCollectionName(collection_name));
4642
status = client->CreateCollection(
4743
milvus::CreateCollectionRequest().WithCollectionName(collection_name).WithCollectionSchema(collection_schema));
4844
util::CheckStatus("create collection: " + collection_name, status);
4945

50-
// create index
51-
milvus::IndexDesc index_vector(field_vector, "", milvus::IndexType::HNSW, milvus::MetricType::L2);
46+
milvus::IndexDesc index_vector(field_vector, "", milvus::IndexType::FLAT, milvus::MetricType::COSINE);
5247
status = client->CreateIndex(
5348
milvus::CreateIndexRequest().WithCollectionName(collection_name).AddIndex(std::move(index_vector)));
5449
util::CheckStatus("create index on vector field", status);
5550

56-
// tell server prepare to load collection
5751
status = client->LoadCollection(milvus::LoadCollectionRequest().WithCollectionName(collection_name));
5852
util::CheckStatus("load collection: " + collection_name, status);
5953

60-
const int64_t row_count = 10;
61-
// insert 10 rows by row-based
62-
{
63-
milvus::EntityRows rows;
64-
for (auto i = 0; i < row_count; ++i) {
65-
milvus::EntityRow row;
66-
row[field_vector] = util::GenerateFloatVector(dimension);
67-
rows.emplace_back(std::move(row));
68-
}
69-
70-
// insert into partition_1
71-
milvus::InsertResponse resp_insert;
72-
status = client->Insert(
73-
milvus::InsertRequest().WithCollectionName(collection_name).WithRowsData(std::move(rows)), resp_insert);
74-
util::CheckStatus("insert", status);
75-
std::cout << resp_insert.Results().InsertCount() << " rows inserted by row-based." << std::endl;
54+
std::cout << "Collection created" << std::endl;
55+
}
56+
57+
void
58+
InsertRow(milvus::MilvusClientV2Ptr& client, int64_t id, const std::string* text) {
59+
milvus::EntityRow row;
60+
row[field_id] = id;
61+
row[field_vector] = util::GenerateFloatVector(dimension);
62+
if (text != nullptr) {
63+
row[field_text] = *text;
64+
}
65+
66+
milvus::EntityRows rows;
67+
rows.emplace_back(std::move(row));
68+
69+
milvus::InsertResponse response;
70+
auto status = client->Insert(
71+
milvus::InsertRequest().WithCollectionName(collection_name).WithRowsData(std::move(rows)), response);
72+
util::CheckStatus("insert", status);
73+
}
74+
75+
void
76+
QueryById(milvus::MilvusClientV2Ptr& client, int64_t id) {
77+
auto request = milvus::QueryRequest()
78+
.WithCollectionName(collection_name)
79+
.AddOutputField("*")
80+
.WithFilter(field_id + " == " + std::to_string(id))
81+
.WithConsistencyLevel(milvus::ConsistencyLevel::STRONG);
82+
83+
std::cout << "\nQuery with id: " << id << std::endl;
84+
milvus::QueryResponse response;
85+
auto status = client->Query(request, response);
86+
util::CheckStatus("query", status);
87+
88+
milvus::EntityRows output_rows;
89+
status = response.Results().OutputRows(output_rows);
90+
util::CheckStatus("get output rows", status);
91+
for (const auto& row : output_rows) {
92+
std::cout << row << std::endl;
93+
}
94+
std::cout << "=============================================================" << std::endl;
95+
}
96+
97+
void
98+
DescribeCollection(milvus::MilvusClientV2Ptr& client) {
99+
milvus::DescribeCollectionResponse response;
100+
auto status =
101+
client->DescribeCollection(milvus::DescribeCollectionRequest().WithCollectionName(collection_name), response);
102+
util::CheckStatus("describe collection", status);
103+
104+
std::cout << "\nCollection fields:" << std::endl;
105+
for (const auto& field : response.Desc().Schema().Fields()) {
106+
std::cout << " " << field.Name() << std::endl;
76107
}
108+
for (const auto& function : response.Desc().Schema().Functions()) {
109+
std::cout << " function: " << function->Name() << std::endl;
110+
}
111+
std::cout << "=============================================================" << std::endl;
112+
}
113+
114+
} // namespace
115+
116+
int
117+
main(int argc, char* argv[]) {
118+
printf("Example start...\n");
119+
120+
auto client = milvus::MilvusClientV2::Create();
121+
122+
milvus::ConnectParam connect_param{"http://localhost:19530", "root:Milvus"};
123+
auto status = client->Connect(connect_param);
124+
util::CheckStatus("connect milvus server", status);
125+
126+
CreateCollection(client);
127+
128+
InsertRow(client, 100, nullptr);
77129

78-
// add more fields to the existing collection
79-
// new fields must be nullable
80130
{
81-
milvus::FieldSchema new_field_1 = milvus::FieldSchema()
82-
.WithName("new_1")
83-
.WithDataType(milvus::DataType::VARCHAR)
84-
.WithMaxLength(64)
85-
.WithNullable(true)
86-
.WithDefaultValue("default text");
87-
auto status = client->AddCollectionField(
88-
milvus::AddCollectionFieldRequest().WithCollectionName(collection_name).WithField(std::move(new_field_1)));
89-
util::CheckStatus("add a new varchar field", status);
90-
91-
milvus::FieldSchema new_field_2 = milvus::FieldSchema()
92-
.WithName("new_2")
93-
.WithDataType(milvus::DataType::ARRAY)
94-
.WithElementType(milvus::DataType::INT16)
95-
.WithMaxCapacity(10)
96-
.WithNullable(true);
131+
milvus::FieldSchema text_field =
132+
milvus::FieldSchema(field_text, milvus::DataType::VARCHAR).WithMaxLength(100).WithNullable(true);
97133
status = client->AddCollectionField(
98-
milvus::AddCollectionFieldRequest().WithCollectionName(collection_name).WithField(std::move(new_field_2)));
99-
util::CheckStatus("add a new array field", status);
134+
milvus::AddCollectionFieldRequest().WithCollectionName(collection_name).WithField(std::move(text_field)));
135+
util::CheckStatus("add field 'text'", status);
136+
137+
DescribeCollection(client);
138+
QueryById(client, 100);
100139
}
101140

102-
// insert another 10 rows by row-based
103141
{
104-
milvus::EntityRows rows;
105-
for (auto i = 0; i < row_count; ++i) {
106-
milvus::EntityRow row;
107-
row[field_vector] = util::GenerateFloatVector(dimension);
108-
row["new_1"] = "inserted value " + std::to_string(i);
109-
row["new_2"] = util::RandomeValues<int16_t>(0, 10, i % 10 + 1);
110-
rows.emplace_back(std::move(row));
111-
}
112-
113-
// insert into partition_1
114-
milvus::InsertResponse resp_insert;
115-
status = client->Insert(
116-
milvus::InsertRequest().WithCollectionName(collection_name).WithRowsData(std::move(rows)), resp_insert);
117-
util::CheckStatus("insert", status);
118-
std::cout << resp_insert.Results().InsertCount() << " rows inserted by row-based." << std::endl;
142+
const std::string text_value = "this is a new row";
143+
InsertRow(client, 500, &text_value);
144+
QueryById(client, 500);
119145
}
120146

121147
{
122-
// verify the row count is 20
123-
auto request = milvus::QueryRequest()
124-
.WithCollectionName(collection_name)
125-
.AddOutputField("count(*)")
126-
.WithConsistencyLevel(
127-
milvus::ConsistencyLevel::STRONG); // set to strong level so that the query is executed
128-
// after the inserted data is consumed by server
129-
130-
milvus::QueryResponse response;
131-
status = client->Query(request, response);
132-
util::CheckStatus("query count(*)", status);
133-
std::cout << "count(*) = " << response.Results().GetRowCount() << std::endl;
148+
status = client->DropCollectionField(
149+
milvus::DropCollectionFieldRequest().WithCollectionName(collection_name).WithFieldName(field_text));
150+
util::CheckStatus("drop field 'text'", status);
151+
std::cout << "Field 'text' dropped" << std::endl;
152+
DescribeCollection(client);
134153
}
135154

136155
{
137-
// query the 10 rows are default values for the added field
138-
auto request = milvus::QueryRequest()
139-
.WithCollectionName(collection_name)
140-
.AddOutputField("*")
141-
.WithFilter("new_1 == 'default text'");
142-
143-
std::cout << "\nQuery with filter: " << request.Filter() << std::endl;
144-
milvus::QueryResponse response;
145-
status = client->Query(request, response);
146-
util::CheckStatus("query", status);
147-
148-
milvus::EntityRows output_rows;
149-
status = response.Results().OutputRows(output_rows);
150-
util::CheckStatus("get output rows", status);
151-
std::cout << "Query results:" << std::endl;
152-
for (const auto& row : output_rows) {
153-
std::cout << "\t" << row << std::endl;
154-
}
156+
milvus::FieldSchema text_field = milvus::FieldSchema(field_text, milvus::DataType::VARCHAR)
157+
.WithMaxLength(100)
158+
.EnableAnalyzer(true)
159+
.EnableMatch(true)
160+
.WithNullable(true);
161+
status = client->AddCollectionField(
162+
milvus::AddCollectionFieldRequest().WithCollectionName(collection_name).WithField(std::move(text_field)));
163+
util::CheckStatus("add field 'text' for function demo", status);
164+
165+
milvus::FieldSchema sparse_field(field_sparse, milvus::DataType::SPARSE_FLOAT_VECTOR);
166+
milvus::FunctionPtr function = std::make_shared<milvus::Function>(function_name, milvus::FunctionType::BM25);
167+
function->AddInputFieldName(field_text);
168+
function->AddOutputFieldName(field_sparse);
169+
170+
status = client->AddFunctionField(milvus::AddFunctionFieldRequest()
171+
.WithCollectionName(collection_name)
172+
.WithField(std::move(sparse_field))
173+
.WithFunction(function));
174+
util::CheckStatus("add function-backed field 'sparse'", status);
175+
std::cout << "Function-backed field 'sparse' added" << std::endl;
176+
DescribeCollection(client);
155177
}
156178

157179
{
158-
// query the 10 rows inserted by Insert() the added field
159-
auto request = milvus::QueryRequest()
160-
.WithCollectionName(collection_name)
161-
.AddOutputField("*")
162-
.WithFilter("ARRAY_LENGTH(new_2) > 0");
163-
164-
std::cout << "\nQuery with filter: " << request.Filter() << std::endl;
165-
milvus::QueryResponse response;
166-
status = client->Query(request, response);
167-
util::CheckStatus("query", status);
168-
169-
milvus::EntityRows output_rows;
170-
status = response.Results().OutputRows(output_rows);
171-
util::CheckStatus("get output rows", status);
172-
std::cout << "Query results:" << std::endl;
173-
for (const auto& row : output_rows) {
174-
std::cout << "\t" << row << std::endl;
175-
}
180+
status = client->DropFunctionField(
181+
milvus::DropFunctionFieldRequest().WithCollectionName(collection_name).WithFunctionName(function_name));
182+
util::CheckStatus("drop function-backed field 'sparse'", status);
183+
std::cout << "Function-backed field 'sparse' dropped" << std::endl;
184+
DescribeCollection(client);
176185
}
177186

178187
client->Disconnect();

0 commit comments

Comments
 (0)