|
| 1 | +// Licensed to the LF AI & Data foundation under one |
| 2 | +// or more contributor license agreements. See the NOTICE file |
| 3 | +// distributed with this work for additional information |
| 4 | +// regarding copyright ownership. The ASF licenses this file |
| 5 | +// to you under the Apache License, Version 2.0 (the |
| 6 | +// "License"); you may not use this file except in compliance |
| 7 | +// with the License. You may obtain a copy of the License at |
| 8 | +// |
| 9 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +// |
| 11 | +// Unless required by applicable law or agreed to in writing, software |
| 12 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +// See the License for the specific language governing permissions and |
| 15 | +// limitations under the License. |
| 16 | + |
| 17 | +#include <iostream> |
| 18 | +#include <string> |
| 19 | +#include <thread> |
| 20 | + |
| 21 | +#include "ExampleUtils.h" |
| 22 | +#include "milvus/MilvusClient.h" |
| 23 | + |
| 24 | +int |
| 25 | +main(int argc, char* argv[]) { |
| 26 | + printf("Example start...\n"); |
| 27 | + |
| 28 | + auto client = milvus::MilvusClient::Create(); |
| 29 | + |
| 30 | + milvus::ConnectParam connect_param{"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 = "TEST_CPP_FILTER_TEMPLATE"; |
| 35 | + const std::string field_id = "pk"; |
| 36 | + const std::string field_vector = "vector"; |
| 37 | + const std::string field_text = "text"; |
| 38 | + const uint32_t dimension = 4; |
| 39 | + |
| 40 | + // collection schema, drop and create collection |
| 41 | + milvus::CollectionSchema collection_schema(collection_name); |
| 42 | + collection_schema.AddField(milvus::FieldSchema(field_id, milvus::DataType::INT64, "", true, true)); |
| 43 | + collection_schema.AddField( |
| 44 | + milvus::FieldSchema(field_vector, milvus::DataType::FLOAT_VECTOR).WithDimension(dimension)); |
| 45 | + collection_schema.AddField(milvus::FieldSchema(field_text, milvus::DataType::VARCHAR).WithMaxLength(1024)); |
| 46 | + |
| 47 | + status = client->DropCollection(collection_name); |
| 48 | + status = client->CreateCollection(collection_schema); |
| 49 | + util::CheckStatus("create collection: " + collection_name, status); |
| 50 | + |
| 51 | + // create index |
| 52 | + milvus::IndexDesc index_vector(field_vector, "", milvus::IndexType::FLAT, milvus::MetricType::L2); |
| 53 | + status = client->CreateIndex(collection_name, index_vector); |
| 54 | + util::CheckStatus("create index on vector field", status); |
| 55 | + |
| 56 | + // tell server prepare to load collection |
| 57 | + status = client->LoadCollection(collection_name); |
| 58 | + util::CheckStatus("load collection: " + collection_name, status); |
| 59 | + |
| 60 | + // insert some rows |
| 61 | + milvus::EntityRows rows; |
| 62 | + for (auto i = 0; i < 10000; ++i) { |
| 63 | + milvus::EntityRow row; // id is auto-generated |
| 64 | + row[field_text] = "text_" + std::to_string(i); |
| 65 | + row[field_vector] = util::GenerateFloatVector(dimension); |
| 66 | + rows.emplace_back(std::move(row)); |
| 67 | + } |
| 68 | + |
| 69 | + milvus::DmlResults dml_results; |
| 70 | + status = client->Insert(collection_name, "", rows, dml_results); |
| 71 | + util::CheckStatus("insert", status); |
| 72 | + std::cout << dml_results.InsertCount() << " rows inserted by row-based." << std::endl; |
| 73 | + auto ids = dml_results.IdArray().IntIDArray(); |
| 74 | + |
| 75 | + { |
| 76 | + // query with filter template |
| 77 | + std::string filter = field_id + " in {my_ids}"; // "my_ids" is an alias will be used in filter template |
| 78 | + std::cout << "Query with filter expression: " << filter << std::endl; |
| 79 | + |
| 80 | + auto begin = ids.begin() + 500; |
| 81 | + auto end = begin + 100; |
| 82 | + std::vector<int64_t> filter_ids(begin, end); |
| 83 | + nlohmann::json filter_template = filter_ids; |
| 84 | + |
| 85 | + milvus::QueryArguments q_arguments{}; |
| 86 | + q_arguments.SetCollectionName(collection_name); |
| 87 | + q_arguments.AddOutputField(field_text); |
| 88 | + q_arguments.SetFilter(filter); |
| 89 | + q_arguments.AddFilterTemplate("my_ids", filter_template); // filter template |
| 90 | + // set to strong level so that the query is executed after the inserted data is consumed by server |
| 91 | + q_arguments.SetConsistencyLevel(milvus::ConsistencyLevel::STRONG); |
| 92 | + |
| 93 | + milvus::QueryResults query_results{}; |
| 94 | + status = client->Query(q_arguments, query_results); |
| 95 | + util::CheckStatus("query", status); |
| 96 | + |
| 97 | + milvus::EntityRows output_rows; |
| 98 | + status = query_results.OutputRows(output_rows); |
| 99 | + util::CheckStatus("get output rows", status); |
| 100 | + std::cout << "Query with filter template:" << std::endl; |
| 101 | + for (const auto& row : output_rows) { |
| 102 | + std::cout << "\t" << row << std::endl; |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + { |
| 107 | + // search with filter template |
| 108 | + std::string filter = field_text + " in {my_texts}"; // "my_texts" is an alias will be used in filter template |
| 109 | + std::vector<std::string> texts; |
| 110 | + for (auto i = 300; i < 500; i++) { |
| 111 | + texts.push_back("text_" + std::to_string(i)); |
| 112 | + } |
| 113 | + nlohmann::json filter_template = texts; |
| 114 | + |
| 115 | + milvus::SearchArguments s_arguments{}; |
| 116 | + s_arguments.SetCollectionName(collection_name); |
| 117 | + s_arguments.SetLimit(static_cast<int64_t>(texts.size())); |
| 118 | + s_arguments.SetFilter(filter); |
| 119 | + s_arguments.AddFilterTemplate("my_texts", filter_template); |
| 120 | + s_arguments.AddOutputField(field_text); |
| 121 | + s_arguments.AddFloatVector(field_vector, util::GenerateFloatVector(dimension)); |
| 122 | + s_arguments.AddFloatVector(field_vector, util::GenerateFloatVector(dimension)); |
| 123 | + s_arguments.SetConsistencyLevel(milvus::ConsistencyLevel::BOUNDED); |
| 124 | + |
| 125 | + milvus::SearchResults search_results{}; |
| 126 | + status = client->Search(s_arguments, search_results); |
| 127 | + util::CheckStatus("search", status); |
| 128 | + |
| 129 | + std::cout << "Search with filter template:" << std::endl; |
| 130 | + for (auto& result : search_results.Results()) { |
| 131 | + std::cout << "Result of one target vector:" << std::endl; |
| 132 | + milvus::EntityRows output_rows; |
| 133 | + status = result.OutputRows(output_rows); |
| 134 | + util::CheckStatus("get output rows", status); |
| 135 | + for (const auto& row : output_rows) { |
| 136 | + std::cout << "\t" << row << std::endl; |
| 137 | + } |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + client->Disconnect(); |
| 142 | + return 0; |
| 143 | +} |
0 commit comments