Filtering by numeric scalar fields prototype (#1919)

* Add hybrid request handler

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add C++ sdk for createcollection and insertentities

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add RequestHandler

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add test case for hybrid insert

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix sqlite bug for createcollection

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add HybridQuery Handler DBImpl and ExecBinaryQuery

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add HybridSearch sdk

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add HybridSearch test case

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix HybridSearch bug

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix HybridSearch crash bug

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Change void* to vector<uint8_t> in Attr codec

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add context and new search task

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add merge for Hybrid

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add AST validation

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add unittest for hybrid

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix hybrid search nq bug

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix bugs after merge master

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix clang format

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix unittest bugs

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix Codacy

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix compact unittest bug

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Remove grpc request in hybridsearchcontext

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix some codacy quality issue

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix HYBRID_DB_TEST bug

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Annotate new search task

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add Hybrid RPC handler unittest

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Fix logs

Signed-off-by: fishpenguin <kun.yu@zilliz.com>

* Add HybridSearch unittest

Signed-off-by: fishpenguin <kun.yu@zilliz.com>
This commit is contained in:
yukun 2020-04-16 14:54:12 +08:00 committed by GitHub
parent 6a36eaa982
commit 3e1b2ab4a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
93 changed files with 46619 additions and 154 deletions

View File

@ -46,6 +46,10 @@ set(grpc_service_files
${MILVUS_ENGINE_SRC}/grpc/gen-status/status.pb.cc
)
aux_source_directory(${MILVUS_ENGINE_SRC}/query query_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/context context_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/search search_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler scheduler_main_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/action scheduler_action_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/scheduler/event scheduler_event_files)
@ -74,11 +78,13 @@ set(thirdparty_files
aux_source_directory(${MILVUS_ENGINE_SRC}/server server_service_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/server/delivery/request delivery_request_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/server/delivery/hybrid_request delivery_hybrid_request_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/server/delivery/strategy delivery_strategy_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/server/delivery delivery_files)
set(server_files
${server_service_files}
${delivery_request_files}
${delivery_hybrid_request_files}
${delivery_strategy_files}
${delivery_files}
)
@ -284,6 +290,9 @@ add_executable(milvus_server
${config_files}
${config_handler_files}
${metrics_files}
${query_files}
${search_files}
${context_files}
${scheduler_files}
${server_files}
${grpc_server_files}

View File

@ -17,17 +17,28 @@
#pragma once
#include <memory>
#include <vector>
#include "segment/Attrs.h"
#include "storage/FSHandler.h"
namespace milvus {
namespace codec {
class AttrsFormat {
// public:
// virtual Attrs
// read() = 0;
//
// virtual void
// write(Attrs attrs) = 0;
public:
virtual void
read(const storage::FSHandlerPtr& fs_ptr, segment::AttrsPtr& attrs_read) = 0;
virtual void
write(const storage::FSHandlerPtr& fs_ptr, const segment::AttrsPtr& attr) = 0;
virtual void
read_uids(const storage::FSHandlerPtr& fs_ptr, std::vector<int64_t>& uids) = 0;
};
using AttrsFormatPtr = std::shared_ptr<AttrsFormat>;
} // namespace codec
} // namespace milvus

View File

@ -33,6 +33,9 @@ class Codec {
virtual VectorsFormatPtr
GetVectorsFormat() = 0;
virtual AttrsFormatPtr
GetAttrsFormat() = 0;
virtual VectorIndexFormatPtr
GetVectorIndexFormat() = 0;

View File

@ -0,0 +1,247 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "codecs/default/DefaultAttrsFormat.h"
#include <fcntl.h>
#include <unistd.h>
#include <algorithm>
#include <memory>
#include <boost/filesystem.hpp>
#include "utils/Exception.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
namespace milvus {
namespace codec {
void
DefaultAttrsFormat::read_attrs_internal(const std::string& file_path, off_t offset, size_t num,
std::vector<uint8_t>& raw_attrs, size_t& nbytes) {
int ra_fd = open(file_path.c_str(), O_RDONLY, 00664);
if (ra_fd == -1) {
std::string err_msg = "Failed to open file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_CANNOT_CREATE_FILE, err_msg);
}
size_t num_bytes;
if (::read(ra_fd, &num_bytes, sizeof(size_t)) == -1) {
std::string err_msg = "Failed to read from file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
num = std::min(num, num_bytes - offset);
offset += sizeof(size_t);
int off = lseek(ra_fd, offset, SEEK_SET);
if (off == -1) {
std::string err_msg = "Failed to seek file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
raw_attrs.resize(num / sizeof(uint8_t));
if (::read(ra_fd, raw_attrs.data(), num) == -1) {
std::string err_msg = "Failed to read from file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
nbytes = num;
if (::close(ra_fd) == -1) {
std::string err_msg = "Failed to close file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
}
void
DefaultAttrsFormat::read_uids_internal(const std::string& file_path, std::vector<int64_t>& uids) {
int uid_fd = open(file_path.c_str(), O_RDONLY, 00664);
if (uid_fd == -1) {
std::string err_msg = "Failed to open file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_CANNOT_CREATE_FILE, err_msg);
}
size_t num_bytes;
if (::read(uid_fd, &num_bytes, sizeof(size_t)) == -1) {
std::string err_msg = "Failed to read from file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
uids.resize(num_bytes / sizeof(int64_t));
if (::read(uid_fd, uids.data(), num_bytes) == -1) {
std::string err_msg = "Failed to read from file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
if (::close(uid_fd) == -1) {
std::string err_msg = "Failed to close file: " + file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
}
void
DefaultAttrsFormat::read(const milvus::storage::FSHandlerPtr& fs_ptr, milvus::segment::AttrsPtr& attrs_read) {
const std::lock_guard<std::mutex> lock(mutex_);
std::string dir_path = fs_ptr->operation_ptr_->GetDirectory();
if (!boost::filesystem::is_directory(dir_path)) {
std::string err_msg = "Directory: " + dir_path + "does not exist";
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_INVALID_ARGUMENT, err_msg);
}
boost::filesystem::path target_path(dir_path);
typedef boost::filesystem::directory_iterator d_it;
d_it it_end;
d_it uid_it(target_path);
std::vector<int64_t> uids;
for (; uid_it != it_end; ++uid_it) {
const auto& path = uid_it->path();
if (path.extension().string() == user_id_extension_) {
read_uids_internal(path.string(), uids);
break;
}
}
d_it it(target_path);
for (; it != it_end; ++it) {
const auto& path = it->path();
if (path.extension().string() == raw_attr_extension_) {
auto file_name = path.filename().string();
auto field_name = file_name.substr(0, file_name.size() - 3);
// void* attr_list;
std::vector<uint8_t> attr_list;
size_t nbytes;
read_attrs_internal(path.string(), 0, INT64_MAX, attr_list, nbytes);
milvus::segment::AttrPtr attr =
std::make_shared<milvus::segment::Attr>(attr_list, nbytes, uids, field_name);
attrs_read->attrs.insert(std::pair(field_name, attr));
}
}
}
void
DefaultAttrsFormat::write(const milvus::storage::FSHandlerPtr& fs_ptr, const milvus::segment::AttrsPtr& attrs_ptr) {
const std::lock_guard<std::mutex> lock(mutex_);
TimeRecorder rc("write attributes");
std::string dir_path = fs_ptr->operation_ptr_->GetDirectory();
auto it = attrs_ptr->attrs.begin();
if (it == attrs_ptr->attrs.end()) {
std::string err_msg = "Attributes is null";
LOG_ENGINE_ERROR_ << err_msg;
return;
}
#if 0
const std::string uid_file_path = dir_path + "/" + it->second->GetCollectionId() + user_id_extension_;
int uid_fd = open(uid_file_path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 00664);
if (uid_fd == -1) {
std::string err_msg = "Failed to open file: " + uid_file_path + ", error: " + std::strerror(errno);
ENGINE_LOG_ERROR << err_msg;
throw Exception(SERVER_CANNOT_CREATE_FILE, err_msg);
}
size_t uid_num_bytes = it->second->GetUids().size() * sizeof(int64_t);
if (::write(uid_fd, &uid_num_bytes, sizeof(size_t)) == -1) {
std::string err_msg = "Failed to write to file" + uid_file_path + ", error: " + std::strerror(errno);
ENGINE_LOG_ERROR << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
if (::write(uid_fd, it->second->GetUids().data(), uid_num_bytes) == -1) {
std::string err_msg = "Failed to write to file" + uid_file_path + ", error: " + std::strerror(errno);
ENGINE_LOG_ERROR << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
if (::close(uid_fd) == -1) {
std::string err_msg = "Failed to close file: " + uid_file_path + ", error: " + std::strerror(errno);
ENGINE_LOG_ERROR << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
rc.RecordSection("write uids done");
#endif
for (; it != attrs_ptr->attrs.end(); it++) {
const std::string ra_file_path = dir_path + "/" + it->second->GetName() + raw_attr_extension_;
int ra_fd = open(ra_file_path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 00664);
if (ra_fd == -1) {
std::string err_msg = "Failed to open file: " + ra_file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_CANNOT_CREATE_FILE, err_msg);
}
size_t ra_num_bytes = it->second->GetNbytes();
if (::write(ra_fd, &ra_num_bytes, sizeof(size_t)) == -1) {
std::string err_msg = "Failed to write to file: " + ra_file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
if (::write(ra_fd, it->second->GetData().data(), ra_num_bytes) == -1) {
std::string err_msg = "Failed to write to file: " + ra_file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
if (::close(ra_fd) == -1) {
std::string err_msg = "Failed to close file: " + ra_file_path + ", error: " + std::strerror(errno);
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_WRITE_ERROR, err_msg);
}
rc.RecordSection("write rv done");
}
}
void
DefaultAttrsFormat::read_uids(const milvus::storage::FSHandlerPtr& fs_ptr, std::vector<int64_t>& uids) {
const std::lock_guard<std::mutex> lock(mutex_);
std::string dir_path = fs_ptr->operation_ptr_->GetDirectory();
if (!boost::filesystem::is_directory(dir_path)) {
std::string err_msg = "Directory: " + dir_path + "does not exist";
LOG_ENGINE_ERROR_ << err_msg;
throw Exception(SERVER_INVALID_ARGUMENT, err_msg);
}
boost::filesystem::path target_path(dir_path);
typedef boost::filesystem::directory_iterator d_it;
d_it it_end;
d_it it(target_path);
// for (auto& it : boost::filesystem::directory_iterator(dir_path)) {
for (; it != it_end; ++it) {
const auto& path = it->path();
if (path.extension().string() == user_id_extension_) {
read_uids_internal(path.string(), uids);
}
}
}
} // namespace codec
} // namespace milvus

View File

@ -0,0 +1,67 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <mutex>
#include <string>
#include <vector>
#include "codecs/AttrsFormat.h"
#include "segment/Attrs.h"
namespace milvus {
namespace codec {
class DefaultAttrsFormat : public AttrsFormat {
public:
DefaultAttrsFormat() = default;
void
read(const storage::FSHandlerPtr& fs_ptr, segment::AttrsPtr& attrs_read) override;
void
write(const storage::FSHandlerPtr& fs_ptr, const segment::AttrsPtr& attr) override;
void
read_uids(const storage::FSHandlerPtr& fs_ptr, std::vector<int64_t>& uids) override;
// No copy and move
DefaultAttrsFormat(const DefaultAttrsFormat&) = delete;
DefaultAttrsFormat(DefaultAttrsFormat&&) = delete;
DefaultAttrsFormat&
operator=(const DefaultAttrsFormat&) = delete;
DefaultAttrsFormat&
operator=(DefaultAttrsFormat&&) = delete;
private:
void
read_attrs_internal(const std::string&, off_t, size_t, std::vector<uint8_t>&, size_t&);
void
read_uids_internal(const std::string&, std::vector<int64_t>&);
private:
std::mutex mutex_;
const std::string raw_attr_extension_ = ".ra";
const std::string user_id_extension_ = ".uid";
};
} // namespace codec
} // namespace milvus

View File

@ -19,6 +19,7 @@
#include <memory>
#include "DefaultAttrsFormat.h"
#include "DefaultDeletedDocsFormat.h"
#include "DefaultIdBloomFilterFormat.h"
#include "DefaultVectorIndexFormat.h"
@ -29,6 +30,7 @@ namespace codec {
DefaultCodec::DefaultCodec() {
vectors_format_ptr_ = std::make_shared<DefaultVectorsFormat>();
attrs_format_ptr_ = std::make_shared<DefaultAttrsFormat>();
vector_index_format_ptr_ = std::make_shared<DefaultVectorIndexFormat>();
deleted_docs_format_ptr_ = std::make_shared<DefaultDeletedDocsFormat>();
id_bloom_filter_format_ptr_ = std::make_shared<DefaultIdBloomFilterFormat>();
@ -39,6 +41,11 @@ DefaultCodec::GetVectorsFormat() {
return vectors_format_ptr_;
}
AttrsFormatPtr
DefaultCodec::GetAttrsFormat() {
return attrs_format_ptr_;
}
VectorIndexFormatPtr
DefaultCodec::GetVectorIndexFormat() {
return vector_index_format_ptr_;

View File

@ -29,6 +29,9 @@ class DefaultCodec : public Codec {
VectorsFormatPtr
GetVectorsFormat() override;
AttrsFormatPtr
GetAttrsFormat() override;
VectorIndexFormatPtr
GetVectorIndexFormat() override;
@ -40,6 +43,7 @@ class DefaultCodec : public Codec {
private:
VectorsFormatPtr vectors_format_ptr_;
AttrsFormatPtr attrs_format_ptr_;
VectorIndexFormatPtr vector_index_format_ptr_;
DeletedDocsFormatPtr deleted_docs_format_ptr_;
IdBloomFilterFormatPtr id_bloom_filter_format_ptr_;

View File

@ -0,0 +1,39 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "query/BinaryQuery.h"
#include "search/Task.h"
namespace milvus {
namespace search {
class Task;
using TaskPtr = std::shared_ptr<Task>;
} // namespace search
namespace context {
struct HybridSearchContext {
query::GeneralQueryPtr general_query_;
std::vector<::milvus::search::TaskPtr> tasks_;
};
using HybridSearchContextPtr = std::shared_ptr<HybridSearchContext>;
} // namespace context
} // namespace milvus

View File

@ -13,11 +13,14 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "Options.h"
#include "Types.h"
#include "context/HybridSearchContext.h"
#include "meta/Meta.h"
#include "query/GeneralQuery.h"
#include "server/context/Context.h"
#include "utils/Status.h"
@ -142,6 +145,23 @@ class DB {
virtual Status
DropAll() = 0;
virtual Status
CreateHybridCollection(meta::CollectionSchema& collection_schema, meta::hybrid::FieldsSchema& fields_schema) = 0;
virtual Status
DescribeHybridCollection(meta::CollectionSchema& collection_schema, meta::hybrid::FieldsSchema& fields_schema) = 0;
virtual Status
InsertEntities(const std::string& collection_id, const std::string& partition_tag, Entity& entity,
std::unordered_map<std::string, meta::hybrid::DataType>& field_types) = 0;
virtual Status
HybridQuery(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, context::HybridSearchContextPtr hybrid_search_context,
query::GeneralQueryPtr general_query,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& attr_type, uint64_t& nq,
engine::ResultIds& result_ids, engine::ResultDistances& result_distances) = 0;
}; // DB
using DBPtr = std::shared_ptr<DB>;

View File

@ -21,8 +21,10 @@
#include <functional>
#include <iostream>
#include <limits>
#include <queue>
#include <set>
#include <thread>
#include <unordered_map>
#include <utility>
#include "Utils.h"
@ -50,6 +52,8 @@
#include "utils/ValidationUtil.h"
#include "wal/WalDefinations.h"
#include "search/TaskInst.h"
namespace milvus {
namespace engine {
@ -208,6 +212,31 @@ DBImpl::CreateCollection(meta::CollectionSchema& collection_schema) {
return meta_ptr_->CreateCollection(temp_schema);
}
Status
DBImpl::CreateHybridCollection(meta::CollectionSchema& collection_schema, meta::hybrid::FieldsSchema& fields_schema) {
if (!initialized_.load(std::memory_order_acquire)) {
return SHUTDOWN_ERROR;
}
meta::CollectionSchema temp_schema = collection_schema;
if (options_.wal_enable_) {
// TODO(yukun): wal_mgr_->CreateHybridCollection()
}
return meta_ptr_->CreateHybridCollection(temp_schema, fields_schema);
}
Status
DBImpl::DescribeHybridCollection(meta::CollectionSchema& collection_schema,
milvus::engine::meta::hybrid::FieldsSchema& fields_schema) {
if (!initialized_.load(std::memory_order_acquire)) {
return SHUTDOWN_ERROR;
}
auto stat = meta_ptr_->DescribeHybridCollection(collection_schema, fields_schema);
return stat;
}
Status
DBImpl::DropCollection(const std::string& collection_id) {
if (!initialized_.load(std::memory_order_acquire)) {
@ -556,6 +585,149 @@ DBImpl::InsertVectors(const std::string& collection_id, const std::string& parti
return status;
}
Status
DBImpl::InsertEntities(const std::string& collection_id, const std::string& partition_tag, Entity& entity,
std::unordered_map<std::string, meta::hybrid::DataType>& attr_types) {
if (!initialized_.load(std::memory_order_acquire)) {
return SHUTDOWN_ERROR;
}
// Generate id
if (entity.id_array_.empty()) {
SafeIDGenerator& id_generator = SafeIDGenerator::GetInstance();
Status status = id_generator.GetNextIDNumbers(entity.entity_count_, entity.id_array_);
if (!status.ok()) {
return status;
}
}
Status status;
// insert entities: collection_name is field id
wal::MXLogRecord record;
record.lsn = 0;
record.collection_id = collection_id;
record.partition_tag = partition_tag;
record.ids = entity.id_array_.data();
record.length = entity.entity_count_;
auto vector_it = entity.vector_data_.begin();
if (vector_it->second.binary_data_.empty()) {
record.type = wal::MXLogType::Entity;
record.data = vector_it->second.float_data_.data();
record.data_size = vector_it->second.float_data_.size() * sizeof(float);
} else {
// record.type = wal::MXLogType::InsertBinary;
// record.data = entities.vector_data_[0].binary_data_.data();
// record.length = entities.vector_data_[0].binary_data_.size() * sizeof(uint8_t);
}
auto attr_data_it = entity.attr_data_.begin();
for (; attr_data_it != entity.attr_data_.end(); ++attr_data_it) {
switch (attr_types.at(attr_data_it->first)) {
case meta::hybrid::DataType::INT8: {
std::vector<int8_t> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atoi(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(int8_t));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(int8_t));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(int8_t)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(int8_t)));
break;
}
case meta::hybrid::DataType::INT16: {
std::vector<int16_t> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atoi(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(int16_t));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(int16_t));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(int16_t)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(int16_t)));
break;
}
case meta::hybrid::DataType::INT32: {
std::vector<int32_t> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atoi(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(int32_t));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(int32_t));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(int32_t)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(int32_t)));
break;
}
case meta::hybrid::DataType::INT64: {
std::vector<int64_t> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atoi(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(int64_t));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(int64_t));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(int64_t)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(int64_t)));
break;
}
case meta::hybrid::DataType::FLOAT: {
std::vector<float> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atof(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(float));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(float));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(float)));
record.attr_data_size.insert(std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(float)));
break;
}
case meta::hybrid::DataType::DOUBLE: {
std::vector<double> entity_data;
entity_data.resize(entity.entity_count_);
for (uint64_t j = 0; j < entity.entity_count_; ++j) {
entity_data[j] = atof(attr_data_it->second[j].c_str());
}
std::vector<uint8_t> data;
data.resize(entity.entity_count_ * sizeof(double));
memcpy(data.data(), entity_data.data(), entity.entity_count_ * sizeof(double));
record.attr_data.insert(std::make_pair(attr_data_it->first, data));
record.attr_nbytes.insert(std::make_pair(attr_data_it->first, sizeof(double)));
record.attr_data_size.insert(
std::make_pair(attr_data_it->first, entity.entity_count_ * sizeof(double)));
break;
}
}
}
status = ExecWalRecord(record);
return status;
}
Status
DBImpl::DeleteVector(const std::string& collection_id, IDNumber vector_id) {
IDNumbers ids;
@ -1121,6 +1293,75 @@ DBImpl::QueryByID(const std::shared_ptr<server::Context>& context, const std::st
return result;
}
Status
DBImpl::HybridQuery(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags,
context::HybridSearchContextPtr hybrid_search_context, query::GeneralQueryPtr general_query,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& attr_type, uint64_t& nq,
ResultIds& result_ids, ResultDistances& result_distances) {
auto query_ctx = context->Child("Query");
if (!initialized_.load(std::memory_order_acquire)) {
return SHUTDOWN_ERROR;
}
Status status;
std::vector<size_t> ids;
meta::SegmentsSchema files_array;
if (partition_tags.empty()) {
// no partition tag specified, means search in whole table
// get all table files from parent table
status = GetFilesToSearch(collection_id, files_array);
if (!status.ok()) {
return status;
}
std::vector<meta::CollectionSchema> partition_array;
status = meta_ptr_->ShowPartitions(collection_id, partition_array);
if (!status.ok()) {
return status;
}
for (auto& schema : partition_array) {
status = GetFilesToSearch(schema.collection_id_, files_array);
if (!status.ok()) {
return Status(DB_ERROR, "GetFilesToSearch failed in HybridQuery");
}
}
if (files_array.empty()) {
return Status::OK();
}
} else {
// get files from specified partitions
std::set<std::string> partition_name_array;
GetPartitionsByTags(collection_id, partition_tags, partition_name_array);
for (auto& partition_name : partition_name_array) {
status = GetFilesToSearch(partition_name, files_array);
if (!status.ok()) {
return Status(DB_ERROR, "GetFilesToSearch failed in HybridQuery");
}
}
if (files_array.empty()) {
return Status::OK();
}
}
cache::CpuCacheMgr::GetInstance()->PrintInfo(); // print cache info before query
status = HybridQueryAsync(query_ctx, collection_id, files_array, hybrid_search_context, general_query, attr_type,
nq, result_ids, result_distances);
if (!status.ok()) {
return status;
}
cache::CpuCacheMgr::GetInstance()->PrintInfo(); // print cache info after query
query_ctx->GetTraceContext()->GetSpan()->Finish();
return status;
}
Status
DBImpl::Query(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, uint64_t k, const milvus::json& extra_params,
@ -1265,6 +1506,70 @@ DBImpl::QueryAsync(const std::shared_ptr<server::Context>& context, const meta::
return Status::OK();
}
Status
DBImpl::HybridQueryAsync(const std::shared_ptr<server::Context>& context, const std::string& table_id,
const meta::SegmentsSchema& files, context::HybridSearchContextPtr hybrid_search_context,
query::GeneralQueryPtr general_query,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& attr_type, uint64_t& nq,
ResultIds& result_ids, ResultDistances& result_distances) {
auto query_async_ctx = context->Child("Query Async");
#if 0
// Construct tasks
for (auto file : files) {
std::unordered_map<std::string, engine::DataType> types;
auto it = attr_type.begin();
for (; it != attr_type.end(); it++) {
types.insert(std::make_pair(it->first, (engine::DataType)it->second));
}
auto file_ptr = std::make_shared<meta::TableFileSchema>(file);
search::TaskPtr
task = std::make_shared<search::Task>(context, file_ptr, general_query, types, hybrid_search_context);
search::TaskInst::GetInstance().load_queue().push(task);
search::TaskInst::GetInstance().load_cv().notify_one();
hybrid_search_context->tasks_.emplace_back(task);
}
#endif
//#if 0
TimeRecorder rc("");
// step 1: construct search job
auto status = OngoingFileChecker::GetInstance().MarkOngoingFiles(files);
VectorsData vectors;
LOG_ENGINE_DEBUG_ << LogOut("Engine query begin, index file count: %ld", files.size());
scheduler::SearchJobPtr job =
std::make_shared<scheduler::SearchJob>(query_async_ctx, general_query, attr_type, vectors);
for (auto& file : files) {
scheduler::SegmentSchemaPtr file_ptr = std::make_shared<meta::SegmentSchema>(file);
job->AddIndexFile(file_ptr);
}
// step 2: put search job to scheduler and wait result
scheduler::JobMgrInst::GetInstance()->Put(job);
job->WaitResult();
status = OngoingFileChecker::GetInstance().UnmarkOngoingFiles(files);
if (!job->GetStatus().ok()) {
return job->GetStatus();
}
// step 3: construct results
nq = job->vector_count();
result_ids = job->GetResultIds();
result_distances = job->GetResultDistances();
rc.ElapseFromBegin("Engine query totally cost");
query_async_ctx->GetTraceContext()->GetSpan()->Finish();
//#endif
return Status::OK();
}
void
DBImpl::BackgroundIndexThread() {
server::SystemInfo::GetInstance().Init();
@ -1464,6 +1769,96 @@ DBImpl::MergeFiles(const std::string& collection_id, const meta::SegmentsSchema&
return status;
}
Status
DBImpl::MergeHybridFiles(const std::string& collection_id, const milvus::engine::meta::SegmentsSchema& files) {
// const std::lock_guard<std::mutex> lock(flush_merge_compact_mutex_);
LOG_ENGINE_DEBUG_ << "Merge files for collection: " << collection_id;
// step 1: create table file
meta::SegmentSchema table_file;
table_file.collection_id_ = collection_id;
table_file.file_type_ = meta::SegmentSchema::NEW_MERGE;
Status status = meta_ptr_->CreateHybridCollectionFile(table_file);
if (!status.ok()) {
LOG_ENGINE_ERROR_ << "Failed to create collection: " << status.ToString();
return status;
}
// step 2: merge files
/*
ExecutionEnginePtr index =
EngineFactory::Build(table_file.dimension_, table_file.location_, (EngineType)table_file.engine_type_,
(MetricType)table_file.metric_type_, table_file.nlist_);
*/
meta::SegmentsSchema updated;
std::string new_segment_dir;
utils::GetParentPath(table_file.location_, new_segment_dir);
auto segment_writer_ptr = std::make_shared<segment::SegmentWriter>(new_segment_dir);
for (auto& file : files) {
server::CollectMergeFilesMetrics metrics;
std::string segment_dir_to_merge;
utils::GetParentPath(file.location_, segment_dir_to_merge);
segment_writer_ptr->Merge(segment_dir_to_merge, table_file.file_id_);
auto file_schema = file;
file_schema.file_type_ = meta::SegmentSchema::TO_DELETE;
updated.push_back(file_schema);
auto size = segment_writer_ptr->Size();
if (size >= file_schema.index_file_size_) {
break;
}
}
// step 3: serialize to disk
try {
status = segment_writer_ptr->Serialize();
fiu_do_on("DBImpl.MergeFiles.Serialize_ThrowException", throw std::exception());
fiu_do_on("DBImpl.MergeFiles.Serialize_ErrorStatus", status = Status(DB_ERROR, ""));
} catch (std::exception& ex) {
std::string msg = "Serialize merged index encounter exception: " + std::string(ex.what());
LOG_ENGINE_ERROR_ << msg;
status = Status(DB_ERROR, msg);
}
if (!status.ok()) {
LOG_ENGINE_ERROR_ << "Failed to persist merged segment: " << new_segment_dir << ". Error: " << status.message();
// if failed to serialize merge file to disk
// typical error: out of disk space, out of memory or permission denied
table_file.file_type_ = meta::SegmentSchema::TO_DELETE;
status = meta_ptr_->UpdateCollectionFile(table_file);
LOG_ENGINE_DEBUG_ << "Failed to update file to index, mark file: " << table_file.file_id_ << " to to_delete";
return status;
}
// step 4: update table files state
// if index type isn't IDMAP, set file type to TO_INDEX if file size exceed index_file_size
// else set file type to RAW, no need to build index
if (!utils::IsRawIndexType(table_file.engine_type_)) {
table_file.file_type_ = (segment_writer_ptr->Size() >= table_file.index_file_size_)
? meta::SegmentSchema::TO_INDEX
: meta::SegmentSchema::RAW;
} else {
table_file.file_type_ = meta::SegmentSchema::RAW;
}
table_file.file_size_ = segment_writer_ptr->Size();
table_file.row_count_ = segment_writer_ptr->VectorCount();
updated.push_back(table_file);
status = meta_ptr_->UpdateCollectionFiles(updated);
LOG_ENGINE_DEBUG_ << "New merged segment " << table_file.segment_id_ << " of size " << segment_writer_ptr->Size()
<< " bytes";
if (options_.insert_cache_immediately_) {
segment_writer_ptr->Cache();
}
return status;
}
Status
DBImpl::BackgroundMergeFiles(const std::string& collection_id) {
const std::lock_guard<std::mutex> lock(flush_merge_compact_mutex_);
@ -1878,6 +2273,23 @@ DBImpl::ExecWalRecord(const wal::MXLogRecord& record) {
Status status;
switch (record.type) {
case wal::MXLogType::Entity: {
std::string target_collection_name;
status = GetPartitionByTag(record.collection_id, record.partition_tag, target_collection_name);
if (!status.ok()) {
return status;
}
std::set<std::string> flushed_tables;
status = mem_mgr_->InsertEntities(target_collection_name, record.length, record.ids,
(record.data_size / record.length / sizeof(float)),
(const float*)record.data, record.attr_nbytes, record.attr_data_size,
record.attr_data, record.lsn, flushed_tables);
collections_flushed(flushed_tables);
milvus::server::CollectInsertMetrics metrics(record.length, status);
break;
}
case wal::MXLogType::InsertBinary: {
std::string target_collection_name;
status = GetPartitionByTag(record.collection_id, record.partition_tag, target_collection_name);

View File

@ -20,6 +20,7 @@
#include <set>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>
#include "config/handler/CacheConfigHandler.h"
@ -134,6 +135,25 @@ class DBImpl : public DB, public server::CacheConfigHandler, public server::Engi
Status
DropIndex(const std::string& collection_id) override;
Status
CreateHybridCollection(meta::CollectionSchema& collection_schema,
meta::hybrid::FieldsSchema& fields_schema) override;
Status
DescribeHybridCollection(meta::CollectionSchema& collection_schema,
meta::hybrid::FieldsSchema& fields_schema) override;
Status
InsertEntities(const std::string& collection_name, const std::string& partition_tag, engine::Entity& entity,
std::unordered_map<std::string, meta::hybrid::DataType>& field_types) override;
Status
HybridQuery(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, context::HybridSearchContextPtr hybrid_search_context,
query::GeneralQueryPtr general_query,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& attr_type, uint64_t& nq,
ResultIds& result_ids, ResultDistances& result_distances) override;
Status
QueryByID(const std::shared_ptr<server::Context>& context, const std::string& collection_id,
const std::vector<std::string>& partition_tags, uint64_t k, const milvus::json& extra_params,
@ -165,6 +185,13 @@ class DBImpl : public DB, public server::CacheConfigHandler, public server::Engi
const milvus::json& extra_params, const VectorsData& vectors, ResultIds& result_ids,
ResultDistances& result_distances);
Status
HybridQueryAsync(const std::shared_ptr<server::Context>& context, const std::string& table_id,
const meta::SegmentsSchema& files, context::HybridSearchContextPtr hybrid_search_context,
query::GeneralQueryPtr general_query,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& attr_type, uint64_t& nq,
ResultIds& result_ids, ResultDistances& result_distances);
Status
GetVectorByIdHelper(const std::string& collection_id, IDNumber vector_id, VectorsData& vector,
const meta::SegmentsSchema& files);
@ -205,6 +232,9 @@ class DBImpl : public DB, public server::CacheConfigHandler, public server::Engi
void
BackgroundMerge(std::set<std::string> collection_ids);
Status
MergeHybridFiles(const std::string& table_id, const meta::SegmentsSchema& files);
void
StartBuildIndexTask();

View File

@ -17,6 +17,7 @@
#include <map>
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
@ -47,6 +48,13 @@ struct VectorsData {
IDNumbers id_array_;
};
struct Entity {
uint64_t entity_count_ = 0;
std::unordered_map<std::string, std::vector<std::string>> attr_data_;
std::unordered_map<std::string, VectorsData> vector_data_;
IDNumbers id_array_;
};
using File2ErrArray = std::map<std::string, std::vector<std::string>>;
using Table2FileErr = std::map<std::string, File2ErrArray>;
using File2RefCount = std::map<std::string, int64_t>;

View File

@ -34,5 +34,26 @@ EngineFactory::Build(uint16_t dimension, const std::string& location, EngineType
return execution_engine_ptr;
}
// ExecutionEnginePtr
// EngineFactory::Build(uint16_t dimension,
// const std::string& location,
// EngineType index_type,
// MetricType metric_type,
// std::unordered_map<std::string, DataType>& attr_type,
// const milvus::json& index_params) {
//
// if (index_type == EngineType::INVALID) {
// ENGINE_LOG_ERROR << "Unsupported engine type";
// return nullptr;
// }
//
// ENGINE_LOG_DEBUG << "EngineFactory index type: " << (int)index_type;
// ExecutionEnginePtr execution_engine_ptr =
// std::make_shared<ExecutionEngineImpl>(dimension, location, index_type, metric_type, attr_type, index_params);
//
// execution_engine_ptr->Init();
// return execution_engine_ptr;
//}
} // namespace engine
} // namespace milvus

View File

@ -25,6 +25,14 @@ class EngineFactory {
static ExecutionEnginePtr
Build(uint16_t dimension, const std::string& location, EngineType index_type, MetricType metric_type,
const milvus::json& index_params);
// static ExecutionEnginePtr
// Build(uint16_t dimension,
// const std::string& location,
// EngineType index_type,
// MetricType metric_type,
// std::unordered_map<std::string, DataType>& attr_type,
// const milvus::json& index_params);
};
} // namespace engine

View File

@ -13,8 +13,12 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <faiss/utils/ConcurrentBitset.h>
#include "query/GeneralQuery.h"
#include "utils/Json.h"
#include "utils/Status.h"
@ -50,6 +54,23 @@ enum class MetricType {
MAX_VALUE = SUPERSTRUCTURE
};
enum class DataType {
INT8 = 1,
INT16 = 2,
INT32 = 3,
INT64 = 4,
STRING = 20,
BOOL = 30,
FLOAT = 40,
DOUBLE = 41,
VECTOR = 100,
UNKNOWN = 9999,
};
class ExecutionEngine {
public:
virtual Status
@ -94,6 +115,11 @@ class ExecutionEngine {
virtual Status
GetVectorByID(const int64_t& id, uint8_t* vector, bool hybrid) = 0;
virtual Status
ExecBinaryQuery(query::GeneralQueryPtr general_query, faiss::ConcurrentBitsetPtr bitset,
std::unordered_map<std::string, DataType>& attr_type, uint64_t& nq, uint64_t& topk,
std::vector<float>& distances, std::vector<int64_t>& labels) = 0;
virtual Status
Search(int64_t n, const float* data, int64_t k, const milvus::json& extra_params, float* distances, int64_t* labels,
bool hybrid) = 0;

View File

@ -15,6 +15,7 @@
#include <fiu-local.h>
#include <stdexcept>
#include <unordered_map>
#include <utility>
#include <vector>
@ -416,6 +417,16 @@ ExecutionEngineImpl::Load(bool to_cache) {
auto& vectors_data = vectors->GetData();
auto attrs = segment_ptr->attrs_ptr_;
auto attrs_it = attrs->attrs.begin();
for (; attrs_it != attrs->attrs.end(); ++attrs_it) {
attr_data_.insert(std::pair(attrs_it->first, attrs_it->second->GetData()));
attr_size_.insert(std::pair(attrs_it->first, attrs_it->second->GetNbytes()));
}
vector_count_ = count;
faiss::ConcurrentBitsetPtr concurrent_bitset_ptr = std::make_shared<faiss::ConcurrentBitset>(count);
for (auto& offset : deleted_docs) {
concurrent_bitset_ptr->set(offset);
@ -704,6 +715,318 @@ MapAndCopyResult(const knowhere::DatasetPtr& dataset, const std::vector<milvus::
free(res_dist);
}
template <typename T>
void
ProcessRangeQuery(std::vector<T> data, T value, query::CompareOperator type, uint64_t j,
faiss::ConcurrentBitsetPtr& bitset) {
switch (type) {
case query::CompareOperator::LT: {
for (uint64_t i = 0; i < data.size(); ++i) {
if (data[i] >= value) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case query::CompareOperator::LTE: {
for (uint64_t i = 0; i < data.size(); ++i) {
if (data[i] > value) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case query::CompareOperator::GT: {
for (uint64_t i = 0; i < data.size(); ++i) {
if (data[i] <= value) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case query::CompareOperator::GTE: {
for (uint64_t i = 0; i < data.size(); ++i) {
if (data[i] < value) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case query::CompareOperator::EQ: {
for (uint64_t i = 0; i < data.size(); ++i) {
if (data[i] != value) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
}
case query::CompareOperator::NE: {
for (uint64_t i = 0; i < data.size(); ++i) {
if (data[i] == value) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
}
}
Status
ExecutionEngineImpl::ExecBinaryQuery(milvus::query::GeneralQueryPtr general_query, faiss::ConcurrentBitsetPtr bitset,
std::unordered_map<std::string, DataType>& attr_type, uint64_t& nq, uint64_t& topk,
std::vector<float>& distances, std::vector<int64_t>& labels) {
if (bitset == nullptr) {
bitset = std::make_shared<faiss::ConcurrentBitset>(vector_count_);
}
if (general_query->leaf == nullptr) {
Status status;
if (general_query->bin->left_query != nullptr) {
status = ExecBinaryQuery(general_query->bin->left_query, bitset, attr_type, nq, topk, distances, labels);
}
if (general_query->bin->right_query != nullptr) {
status = ExecBinaryQuery(general_query->bin->right_query, bitset, attr_type, nq, topk, distances, labels);
}
return status;
} else {
if (general_query->leaf->term_query != nullptr) {
// process attrs_data
auto field_name = general_query->leaf->term_query->field_name;
auto type = attr_type.at(field_name);
auto size = attr_size_.at(field_name);
switch (type) {
case DataType::INT8: {
std::vector<int8_t> data;
data.resize(size / sizeof(int8_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
int8_t query_value = atoi(term_value.c_str());
if (data[i] == query_value) {
value_in_term = true;
break;
}
}
if (!value_in_term) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case DataType::INT16: {
std::vector<int16_t> data;
data.resize(size / sizeof(int16_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
int16_t query_value = atoi(term_value.c_str());
if (data[i] == query_value) {
value_in_term = true;
break;
}
}
if (!value_in_term) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case DataType::INT32: {
std::vector<int32_t> data;
data.resize(size / sizeof(int32_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
int32_t query_value = atoi(term_value.c_str());
if (data[i] == query_value) {
value_in_term = true;
break;
}
}
if (!value_in_term) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case DataType::INT64: {
std::vector<int64_t> data;
data.resize(size / sizeof(int64_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
int64_t query_value = atoi(term_value.c_str());
if (data[i] == query_value) {
value_in_term = true;
break;
}
}
if (!value_in_term) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case DataType::FLOAT: {
std::vector<float> data;
data.resize(size / sizeof(float));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
std::istringstream iss(term_value);
float query_value;
iss >> query_value;
if (data[i] == query_value) {
value_in_term = true;
break;
}
}
if (!value_in_term) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
case DataType::DOUBLE: {
std::vector<double> data;
data.resize(size / sizeof(double));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
for (uint64_t i = 0; i < data.size(); ++i) {
bool value_in_term = false;
for (auto term_value : general_query->leaf->term_query->field_value) {
std::istringstream iss(term_value);
double query_value;
iss >> query_value;
if (data[i] == query_value) {
value_in_term = true;
break;
}
}
if (!value_in_term) {
if (!bitset->test(i)) {
bitset->set(i);
}
}
}
break;
}
}
return Status::OK();
}
if (general_query->leaf->range_query != nullptr) {
auto field_name = general_query->leaf->range_query->field_name;
auto com_expr = general_query->leaf->range_query->compare_expr;
auto type = attr_type.at(field_name);
auto size = attr_size_.at(field_name);
for (uint64_t j = 0; j < com_expr.size(); ++j) {
auto operand = com_expr[j].operand;
switch (type) {
case DataType::INT8: {
std::vector<int8_t> data;
data.resize(size / sizeof(int8_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
int8_t value = atoi(operand.c_str());
ProcessRangeQuery<int8_t>(data, value, com_expr[j].compare_operator, j, bitset);
break;
}
case DataType::INT16: {
std::vector<int16_t> data;
data.resize(size / sizeof(int16_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
int16_t value = atoi(operand.c_str());
ProcessRangeQuery<int16_t>(data, value, com_expr[j].compare_operator, j, bitset);
break;
}
case DataType::INT32: {
std::vector<int32_t> data;
data.resize(size / sizeof(int32_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
int32_t value = atoi(operand.c_str());
ProcessRangeQuery<int32_t>(data, value, com_expr[j].compare_operator, j, bitset);
break;
}
case DataType::INT64: {
std::vector<int64_t> data;
data.resize(size / sizeof(int64_t));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
int64_t value = atoi(operand.c_str());
ProcessRangeQuery<int64_t>(data, value, com_expr[j].compare_operator, j, bitset);
break;
}
case DataType::FLOAT: {
std::vector<float> data;
data.resize(size / sizeof(float));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
std::istringstream iss(operand);
double value;
iss >> value;
ProcessRangeQuery<float>(data, value, com_expr[j].compare_operator, j, bitset);
break;
}
case DataType::DOUBLE: {
std::vector<double> data;
data.resize(size / sizeof(double));
memcpy(data.data(), attr_data_.at(field_name).data(), size);
std::istringstream iss(operand);
double value;
iss >> value;
ProcessRangeQuery<double>(data, value, com_expr[j].compare_operator, j, bitset);
break;
}
}
}
return Status::OK();
}
if (general_query->leaf->vector_query != nullptr) {
// Do search
faiss::ConcurrentBitsetPtr list;
list = index_->GetBlacklist();
// Do OR
for (uint64_t i = 0; i < vector_count_; ++i) {
if (list->test(i) || bitset->test(i)) {
bitset->set(i);
}
}
index_->SetBlacklist(bitset);
auto vector_query = general_query->leaf->vector_query;
topk = vector_query->topk;
nq = vector_query->query_vector.float_data.size() / dim_;
distances.resize(nq * topk);
labels.resize(nq * topk);
return Search(nq, vector_query->query_vector.float_data.data(), topk, vector_query->extra_params,
distances.data(), labels.data());
}
}
}
Status
ExecutionEngineImpl::Search(int64_t n, const float* data, int64_t k, const milvus::json& extra_params, float* distances,
int64_t* labels, bool hybrid) {

View File

@ -16,6 +16,7 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "ExecutionEngine.h"
@ -68,6 +69,11 @@ class ExecutionEngineImpl : public ExecutionEngine {
Status
GetVectorByID(const int64_t& id, uint8_t* vector, bool hybrid) override;
Status
ExecBinaryQuery(query::GeneralQueryPtr general_query, faiss::ConcurrentBitsetPtr bitset,
std::unordered_map<std::string, DataType>& attr_type, uint64_t& nq, uint64_t& topk,
std::vector<float>& distances, std::vector<int64_t>& labels) override;
Status
Search(int64_t n, const float* data, int64_t k, const milvus::json& extra_params, float* distances, int64_t* labels,
bool hybrid = false) override;
@ -122,6 +128,12 @@ class ExecutionEngineImpl : public ExecutionEngine {
EngineType index_type_;
MetricType metric_type_;
std::unordered_map<std::string, DataType> attr_types_;
std::unordered_map<std::string, std::vector<uint8_t>> attr_data_;
std::unordered_map<std::string, size_t> attr_size_;
query::BinaryQueryPtr binary_query_;
int64_t vector_count_;
int64_t dim_;
std::string location_;

View File

@ -14,6 +14,8 @@
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include "db/Types.h"
#include "utils/Status.h"
@ -31,6 +33,13 @@ class MemManager {
InsertVectors(const std::string& collection_id, int64_t length, const IDNumber* vector_ids, int64_t dim,
const uint8_t* vectors, uint64_t lsn, std::set<std::string>& flushed_tables) = 0;
virtual Status
InsertEntities(const std::string& table_id, int64_t length, const IDNumber* vector_ids, int64_t dim,
const float* vectors, const std::unordered_map<std::string, uint64_t>& attr_nbytes,
const std::unordered_map<std::string, uint64_t>& attr_size,
const std::unordered_map<std::string, std::vector<uint8_t>>& attr_data, uint64_t lsn,
std::set<std::string>& flushed_tables) = 0;
virtual Status
DeleteVector(const std::string& collection_id, IDNumber vector_id, uint64_t lsn) = 0;

View File

@ -85,6 +85,36 @@ MemManagerImpl::InsertVectors(const std::string& collection_id, int64_t length,
return InsertVectorsNoLock(collection_id, source, lsn);
}
Status
MemManagerImpl::InsertEntities(const std::string& table_id, int64_t length, const IDNumber* vector_ids, int64_t dim,
const float* vectors, const std::unordered_map<std::string, uint64_t>& attr_nbytes,
const std::unordered_map<std::string, uint64_t>& attr_size,
const std::unordered_map<std::string, std::vector<uint8_t>>& attr_data, uint64_t lsn,
std::set<std::string>& flushed_tables) {
flushed_tables.clear();
if (GetCurrentMem() > options_.insert_buffer_size_) {
LOG_ENGINE_DEBUG_ << LogOut("[%s][%ld] ", "insert", 0)
<< "Insert buffer size exceeds limit. Performing force flush";
auto status = Flush(flushed_tables, false);
if (!status.ok()) {
return status;
}
}
VectorsData vectors_data;
vectors_data.vector_count_ = length;
vectors_data.float_data_.resize(length * dim);
memcpy(vectors_data.float_data_.data(), vectors, length * dim * sizeof(float));
vectors_data.id_array_.resize(length);
memcpy(vectors_data.id_array_.data(), vector_ids, length * sizeof(IDNumber));
VectorSourcePtr source = std::make_shared<VectorSource>(vectors_data, attr_nbytes, attr_size, attr_data);
std::unique_lock<std::mutex> lock(mutex_);
return InsertEntitiesNoLock(table_id, source, lsn);
}
Status
MemManagerImpl::InsertVectorsNoLock(const std::string& collection_id, const VectorSourcePtr& source, uint64_t lsn) {
MemTablePtr mem = GetMemByTable(collection_id);
@ -94,6 +124,16 @@ MemManagerImpl::InsertVectorsNoLock(const std::string& collection_id, const Vect
return status;
}
Status
MemManagerImpl::InsertEntitiesNoLock(const std::string& collection_id, const milvus::engine::VectorSourcePtr& source,
uint64_t lsn) {
MemTablePtr mem = GetMemByTable(collection_id);
mem->SetLSN(lsn);
auto status = mem->AddEntities(source);
return status;
}
Status
MemManagerImpl::DeleteVector(const std::string& collection_id, IDNumber vector_id, uint64_t lsn) {
std::unique_lock<std::mutex> lock(mutex_);

View File

@ -17,6 +17,7 @@
#include <mutex>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include "config/Config.h"
@ -48,6 +49,13 @@ class MemManagerImpl : public MemManager, public server::CacheConfigHandler {
InsertVectors(const std::string& collection_id, int64_t length, const IDNumber* vector_ids, int64_t dim,
const uint8_t* vectors, uint64_t lsn, std::set<std::string>& flushed_tables) override;
Status
InsertEntities(const std::string& table_id, int64_t length, const IDNumber* vector_ids, int64_t dim,
const float* vectors, const std::unordered_map<std::string, uint64_t>& attr_nbytes,
const std::unordered_map<std::string, uint64_t>& attr_size,
const std::unordered_map<std::string, std::vector<uint8_t>>& attr_data, uint64_t lsn,
std::set<std::string>& flushed_tables) override;
Status
DeleteVector(const std::string& collection_id, IDNumber vector_id, uint64_t lsn) override;
@ -86,6 +94,9 @@ class MemManagerImpl : public MemManager, public server::CacheConfigHandler {
Status
InsertVectorsNoLock(const std::string& collection_id, const VectorSourcePtr& source, uint64_t lsn);
Status
InsertEntitiesNoLock(const std::string& collection_id, const VectorSourcePtr& source, uint64_t lsn);
Status
ToImmutable();

View File

@ -60,6 +60,34 @@ MemTable::Add(const VectorSourcePtr& source) {
return Status::OK();
}
Status
MemTable::AddEntities(const milvus::engine::VectorSourcePtr& source) {
while (!source->AllAdded()) {
MemTableFilePtr current_mem_table_file;
if (!mem_table_file_list_.empty()) {
current_mem_table_file = mem_table_file_list_.back();
}
Status status;
if (mem_table_file_list_.empty() || current_mem_table_file->IsFull()) {
MemTableFilePtr new_mem_table_file = std::make_shared<MemTableFile>(collection_id_, meta_, options_);
status = new_mem_table_file->AddEntities(source);
if (status.ok()) {
mem_table_file_list_.emplace_back(new_mem_table_file);
}
} else {
status = current_mem_table_file->AddEntities(source);
}
if (!status.ok()) {
std::string err_msg = "Insert failed: " + status.ToString();
LOG_ENGINE_ERROR_ << LogOut("[%s][%ld] ", "insert", 0) << err_msg;
return Status(DB_ERROR, err_msg);
}
}
return Status::OK();
}
Status
MemTable::Delete(segment::doc_id_t doc_id) {
// Locate which collection file the doc id lands in

View File

@ -35,6 +35,9 @@ class MemTable : public server::CacheConfigHandler {
Status
Add(const VectorSourcePtr& source);
Status
AddEntities(const VectorSourcePtr& source);
Status
Delete(segment::doc_id_t doc_id);

View File

@ -85,6 +85,33 @@ MemTableFile::Add(const VectorSourcePtr& source) {
return Status::OK();
}
Status
MemTableFile::AddEntities(const VectorSourcePtr& source) {
if (table_file_schema_.dimension_ <= 0) {
std::string err_msg =
"MemTableFile::Add: table_file_schema dimension = " + std::to_string(table_file_schema_.dimension_) +
", table_id = " + table_file_schema_.collection_id_;
LOG_ENGINE_ERROR_ << LogOut("[%s][%ld]", "insert", 0) << err_msg;
return Status(DB_ERROR, "Not able to create table file");
}
size_t single_entity_mem_size = source->SingleEntitySize(table_file_schema_.dimension_);
size_t mem_left = GetMemLeft();
if (mem_left >= single_entity_mem_size) {
size_t num_entities_to_add = std::ceil(mem_left / single_entity_mem_size);
size_t num_entities_added;
auto status =
source->AddEntities(segment_writer_ptr_, table_file_schema_, num_entities_to_add, num_entities_added);
if (status.ok()) {
current_mem_ += (num_entities_added * single_entity_mem_size);
}
return status;
}
return Status::OK();
}
Status
MemTableFile::Delete(segment::doc_id_t doc_id) {
segment::SegmentPtr segment_ptr;

View File

@ -36,6 +36,9 @@ class MemTableFile : public server::CacheConfigHandler {
Status
Add(const VectorSourcePtr& source);
Status
AddEntities(const VectorSourcePtr& source);
Status
Delete(segment::doc_id_t doc_id);

View File

@ -26,6 +26,15 @@ VectorSource::VectorSource(VectorsData vectors) : vectors_(std::move(vectors)) {
current_num_vectors_added = 0;
}
VectorSource::VectorSource(milvus::engine::VectorsData vectors,
const std::unordered_map<std::string, uint64_t>& attr_nbytes,
const std::unordered_map<std::string, uint64_t>& attr_size,
const std::unordered_map<std::string, std::vector<uint8_t>>& attr_data)
: vectors_(std::move(vectors)), attr_nbytes_(attr_nbytes), attr_size_(attr_size), attr_data_(attr_data) {
current_num_vectors_added = 0;
current_num_attrs_added = 0;
}
Status
VectorSource::Add(/*const ExecutionEnginePtr& execution_engine,*/ const segment::SegmentWriterPtr& segment_writer_ptr,
const meta::SegmentSchema& table_file_schema, const size_t& num_vectors_to_add,
@ -96,6 +105,61 @@ VectorSource::Add(/*const ExecutionEnginePtr& execution_engine,*/ const segment:
return status;
}
Status
VectorSource::AddEntities(const milvus::segment::SegmentWriterPtr& segment_writer_ptr,
const milvus::engine::meta::SegmentSchema& collection_file_schema,
const size_t& num_entities_to_add, size_t& num_entities_added) {
// TODO: n = vectors_.vector_count_;???
uint64_t n = vectors_.vector_count_;
num_entities_added =
current_num_attrs_added + num_entities_to_add <= n ? num_entities_to_add : n - current_num_attrs_added;
IDNumbers vector_ids_to_add;
if (vectors_.id_array_.empty()) {
SafeIDGenerator& id_generator = SafeIDGenerator::GetInstance();
Status status = id_generator.GetNextIDNumbers(num_entities_added, vector_ids_to_add);
if (!status.ok()) {
return status;
}
} else {
vector_ids_to_add.resize(num_entities_added);
for (size_t pos = current_num_attrs_added; pos < current_num_attrs_added + num_entities_added; pos++) {
vector_ids_to_add[pos - current_num_attrs_added] = vectors_.id_array_[pos];
}
}
Status status;
status =
segment_writer_ptr->AddAttrs(collection_file_schema.collection_id_, attr_size_, attr_data_, vector_ids_to_add);
if (status.ok()) {
current_num_attrs_added += num_entities_added;
} else {
LOG_ENGINE_ERROR_ << LogOut("[%s][%ld]", "insert", 0) << "Generate ids fail: " << status.message();
return status;
}
std::vector<uint8_t> vectors;
auto size = num_entities_added * collection_file_schema.dimension_ * sizeof(float);
vectors.resize(size);
memcpy(vectors.data(), vectors_.float_data_.data() + current_num_vectors_added * collection_file_schema.dimension_,
size);
LOG_ENGINE_DEBUG_ << LogOut("[%s][%ld]", "insert", 0) << "Insert into segment";
status = segment_writer_ptr->AddVectors(collection_file_schema.file_id_, vectors, vector_ids_to_add);
if (status.ok()) {
current_num_vectors_added += num_entities_added;
vector_ids_.insert(vector_ids_.end(), std::make_move_iterator(vector_ids_to_add.begin()),
std::make_move_iterator(vector_ids_to_add.end()));
}
// don't need to add current_num_attrs_added again
if (!status.ok()) {
LOG_ENGINE_ERROR_ << LogOut("[%s][%ld]", "insert", 0) << "VectorSource::Add failed: " + status.ToString();
return status;
}
return status;
}
size_t
VectorSource::GetNumVectorsAdded() {
return current_num_vectors_added;
@ -111,6 +175,17 @@ VectorSource::SingleVectorSize(uint16_t dimension) {
return 0;
}
size_t
VectorSource::SingleEntitySize(uint16_t dimension) {
// TODO(yukun) add entity type and size compute
size_t size = 0;
size += dimension * FLOAT_TYPE_SIZE;
auto nbyte_it = attr_nbytes_.begin();
for (; nbyte_it != attr_nbytes_.end(); ++nbyte_it) {
size += nbyte_it->second;
}
return size;
}
bool
VectorSource::AllAdded() {

View File

@ -12,6 +12,9 @@
#pragma once
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "db/IDGenerator.h"
#include "db/engine/ExecutionEngine.h"
@ -28,16 +31,27 @@ class VectorSource {
public:
explicit VectorSource(VectorsData vectors);
VectorSource(VectorsData vectors, const std::unordered_map<std::string, uint64_t>& attr_nbytes,
const std::unordered_map<std::string, uint64_t>& attr_size,
const std::unordered_map<std::string, std::vector<uint8_t>>& attr_data);
Status
Add(/*const ExecutionEnginePtr& execution_engine,*/ const segment::SegmentWriterPtr& segment_writer_ptr,
const meta::SegmentSchema& table_file_schema, const size_t& num_vectors_to_add, size_t& num_vectors_added);
Status
AddEntities(const segment::SegmentWriterPtr& segment_writer_ptr, const meta::SegmentSchema& collection_file_schema,
const size_t& num_attrs_to_add, size_t& num_attrs_added);
size_t
GetNumVectorsAdded();
size_t
SingleVectorSize(uint16_t dimension);
size_t
SingleEntitySize(uint16_t dimension);
bool
AllAdded();
@ -47,8 +61,12 @@ class VectorSource {
private:
VectorsData vectors_;
IDNumbers vector_ids_;
const std::unordered_map<std::string, uint64_t> attr_nbytes_;
std::unordered_map<std::string, uint64_t> attr_size_;
std::unordered_map<std::string, std::vector<uint8_t>> attr_data_;
size_t current_num_vectors_added;
size_t current_num_attrs_added;
}; // VectorSource
using VectorSourcePtr = std::shared_ptr<VectorSource>;

View File

@ -28,6 +28,9 @@ namespace meta {
static const char* META_ENVIRONMENT = "Environment";
static const char* META_TABLES = "Tables";
static const char* META_TABLEFILES = "TableFiles";
static const char* META_COLLECTIONS = "Collections";
static const char* META_FIELDS = "Fields";
static const char* META_COLLECTIONFILES = "CollectionFiles";
class Meta {
/*
@ -151,6 +154,15 @@ class Meta {
virtual Status
GetGlobalLastLSN(uint64_t& lsn) = 0;
virtual Status
CreateHybridCollection(CollectionSchema& collection_schema, hybrid::FieldsSchema& fields_schema) = 0;
virtual Status
DescribeHybridCollection(CollectionSchema& collection_schema, hybrid::FieldsSchema& fields_schema) = 0;
virtual Status
CreateHybridCollectionFile(SegmentSchema& file_schema) = 0;
}; // MetaData
using MetaPtr = std::shared_ptr<Meta>;

View File

@ -97,6 +97,129 @@ struct SegmentSchema {
using SegmentSchemaPtr = std::shared_ptr<meta::SegmentSchema>;
using SegmentsSchema = std::vector<SegmentSchema>;
namespace hybrid {
enum class DataType {
INT8 = 1,
INT16 = 2,
INT32 = 3,
INT64 = 4,
STRING = 20,
BOOL = 30,
FLOAT = 40,
DOUBLE = 41,
VECTOR = 100,
UNKNOWN = 9999,
};
struct VectorFieldSchema {
std::string vector_id_;
int64_t dimension;
int64_t index_file_size_ = DEFAULT_INDEX_FILE_SIZE;
int32_t engine_type_ = DEFAULT_ENGINE_TYPE;
std::string index_params_ = "{}";
int32_t metric_type_ = DEFAULT_METRIC_TYPE;
};
struct VectorFieldsSchema {
std::vector<VectorFieldSchema> vector_fields_;
};
using VectorFieldSchemaPtr = std::shared_ptr<VectorFieldSchema>;
struct CollectionSchema {
typedef enum {
NORMAL,
TO_DELETE,
} COLLETION_STATE;
size_t id_ = 0;
std::string collection_id_;
int32_t state_ = (int)NORMAL;
int64_t field_num = 0;
int64_t created_on_ = 0;
int64_t flag_ = 0;
std::string owner_collection_;
std::string partition_tag_;
std::string version_ = CURRENT_VERSION;
uint64_t flush_lsn_ = 0;
};
using CollectionSchemaPtr = std::shared_ptr<CollectionSchema>;
struct FieldSchema {
typedef enum {
INT8 = 1,
INT16 = 2,
INT32 = 3,
INT64 = 4,
STRING = 20,
BOOL = 30,
FLOAT = 40,
DOUBLE = 41,
VECTOR = 100,
UNKNOWN = 9999,
} FIELD_TYPE;
// TODO(yukun): need field_id?
std::string collection_id_;
std::string field_name_;
int32_t field_type_ = (int)INT8;
std::string field_params_;
};
struct FieldsSchema {
std::vector<FieldSchema> fields_schema_;
};
using FieldSchemaPtr = std::shared_ptr<FieldSchema>;
struct VectorFileSchema {
std::string field_name_;
int64_t index_file_size_ = DEFAULT_INDEX_FILE_SIZE; // not persist to meta
int32_t engine_type_ = DEFAULT_ENGINE_TYPE;
std::string index_params_ = "{}"; // not persist to meta
int32_t metric_type_ = DEFAULT_METRIC_TYPE; // not persist to meta
};
using VectorFileSchemaPtr = std::shared_ptr<VectorFileSchema>;
struct CollectionFileSchema {
typedef enum {
NEW,
RAW,
TO_INDEX,
INDEX,
TO_DELETE,
NEW_MERGE,
NEW_INDEX,
BACKUP,
} FILE_TYPE;
size_t id_ = 0;
std::string collection_id_;
std::string segment_id_;
std::string file_id_;
int32_t file_type_ = NEW;
size_t file_size_ = 0;
size_t row_count_ = 0;
DateT date_ = EmptyDate;
std::string location_;
int64_t updated_time_ = 0;
int64_t created_on_ = 0;
uint64_t flush_lsn_ = 0;
};
using CollectionFileSchemaPtr = std::shared_ptr<CollectionFileSchema>;
} // namespace hybrid
} // namespace meta
} // namespace engine
} // namespace milvus

View File

@ -2631,6 +2631,18 @@ MySQLMetaImpl::GetGlobalLastLSN(uint64_t& lsn) {
return Status::OK();
}
Status
MySQLMetaImpl::CreateHybridCollection(CollectionSchema& collection_schema, hybrid::FieldsSchema& fields_schema) {
}
Status
MySQLMetaImpl::DescribeHybridCollection(CollectionSchema& collection_schema, hybrid::FieldsSchema& fields_schema) {
}
Status
MySQLMetaImpl::CreateHybridCollectionFile(milvus::engine::meta::SegmentSchema& file_schema) {
}
} // namespace meta
} // namespace engine
} // namespace milvus

View File

@ -142,6 +142,15 @@ class MySQLMetaImpl : public Meta {
Status
GetGlobalLastLSN(uint64_t& lsn) override;
Status
CreateHybridCollection(CollectionSchema& collection_schema, hybrid::FieldsSchema& fields_schema) override;
Status
DescribeHybridCollection(CollectionSchema& collection_schema, hybrid::FieldsSchema& fields_schema) override;
Status
CreateHybridCollectionFile(SegmentSchema& file_schema) override;
private:
Status
NextFileId(std::string& file_id);

View File

@ -75,6 +75,10 @@ StoragePrototype(const std::string& path) {
make_column("partition_tag", &CollectionSchema::partition_tag_, default_value("")),
make_column("version", &CollectionSchema::version_, default_value(CURRENT_VERSION)),
make_column("flush_lsn", &CollectionSchema::flush_lsn_)),
make_table(META_FIELDS, make_column("collection_id", &hybrid::FieldSchema::collection_id_),
make_column("field_name", &hybrid::FieldSchema::field_name_),
make_column("field_type", &hybrid::FieldSchema::field_type_),
make_column("field_params", &hybrid::FieldSchema::field_params_)),
make_table(
META_TABLEFILES, make_column("id", &SegmentSchema::id_, primary_key()),
make_column("table_id", &SegmentSchema::collection_id_),
@ -88,9 +92,46 @@ StoragePrototype(const std::string& path) {
make_column("flush_lsn", &SegmentSchema::flush_lsn_)));
}
using ConnectorT = decltype(StoragePrototype(""));
inline auto
CollectionPrototype(const std::string& path) {
return make_storage(
path,
make_table(META_ENVIRONMENT, make_column("global_lsn", &EnvironmentSchema::global_lsn_, default_value(0))),
make_table(META_COLLECTIONS, make_column("id", &hybrid::CollectionSchema::id_, primary_key()),
make_column("collection_id", &hybrid::CollectionSchema::collection_id_, unique()),
make_column("state", &hybrid::CollectionSchema::state_),
make_column("field_num", &hybrid::CollectionSchema::field_num),
make_column("created_on", &hybrid::CollectionSchema::created_on_),
make_column("flag", &hybrid::CollectionSchema::flag_, default_value(0)),
make_column("owner_collection", &hybrid::CollectionSchema::owner_collection_, default_value("")),
make_column("partition_tag", &hybrid::CollectionSchema::partition_tag_, default_value("")),
make_column("version", &hybrid::CollectionSchema::version_, default_value(CURRENT_VERSION)),
make_column("flush_lsn", &hybrid::CollectionSchema::flush_lsn_)),
make_table(META_FIELDS, make_column("collection_id", &hybrid::FieldSchema::collection_id_),
make_column("field_name", &hybrid::FieldSchema::field_name_),
make_column("field_type", &hybrid::FieldSchema::field_type_),
make_column("field_params", &hybrid::FieldSchema::field_params_)),
make_table(
META_COLLECTIONFILES,
make_column("id", &hybrid::CollectionFileSchema::id_, primary_key()),
make_column("collection_id", &hybrid::CollectionFileSchema::collection_id_),
make_column("segment_id", &hybrid::CollectionFileSchema::segment_id_, default_value("")),
make_column("file_id", &hybrid::CollectionFileSchema::file_id_),
make_column("file_type", &hybrid::CollectionFileSchema::file_type_),
make_column("file_size", &hybrid::CollectionFileSchema::file_size_, default_value(0)),
make_column("row_count", &hybrid::CollectionFileSchema::row_count_, default_value(0)),
make_column("updated_time", &hybrid::CollectionFileSchema::updated_time_),
make_column("created_on", &hybrid::CollectionFileSchema::created_on_),
make_column("date", &hybrid::CollectionFileSchema::date_),
make_column("flush_lsn", &hybrid::CollectionFileSchema::flush_lsn_)));
}
using ConnectorT = decltype(StoragePrototype("table"));
static std::unique_ptr<ConnectorT> ConnectorPtr;
using CollectionConnectT = decltype(CollectionPrototype(""));
static std::unique_ptr<CollectionConnectT> CollectionConnectPtr;
SqliteMetaImpl::SqliteMetaImpl(const DBMetaOptions& options) : options_(options) {
Initialize();
}
@ -132,12 +173,40 @@ SqliteMetaImpl::ValidateMetaSchema() {
sqlite_orm::sync_schema_result::dropped_and_recreated == ret[META_TABLES]) {
throw Exception(DB_INCOMPATIB_META, "Meta Tables schema is created by Milvus old version");
}
if (ret.find(META_FIELDS) != ret.end()
&& sqlite_orm::sync_schema_result::dropped_and_recreated == ret[META_FIELDS]) {
throw Exception(DB_INCOMPATIB_META, "Meta Tables schema is created by Milvus old version");
}
if (ret.find(META_TABLEFILES) != ret.end() &&
sqlite_orm::sync_schema_result::dropped_and_recreated == ret[META_TABLEFILES]) {
throw Exception(DB_INCOMPATIB_META, "Meta TableFiles schema is created by Milvus old version");
}
}
void
SqliteMetaImpl::ValidateCollectionMetaSchema() {
bool is_null_connector{CollectionConnectPtr == nullptr};
fiu_do_on("SqliteMetaImpl.ValidateMetaSchema.NullConnection", is_null_connector = true);
if (is_null_connector) {
return;
}
// old meta could be recreated since schema changed, throw exception if meta schema is not compatible
auto ret = CollectionConnectPtr->sync_schema_simulate();
if (ret.find(META_COLLECTIONS) != ret.end() &&
sqlite_orm::sync_schema_result::dropped_and_recreated == ret[META_COLLECTIONS]) {
throw Exception(DB_INCOMPATIB_META, "Meta Tables schema is created by Milvus old version");
}
if (ret.find(META_FIELDS) != ret.end()
&& sqlite_orm::sync_schema_result::dropped_and_recreated == ret[META_FIELDS]) {
throw Exception(DB_INCOMPATIB_META, "Meta Tables schema is created by Milvus old version");
}
if (ret.find(META_COLLECTIONFILES) != ret.end() &&
sqlite_orm::sync_schema_result::dropped_and_recreated == ret[META_TABLEFILES]) {
throw Exception(DB_INCOMPATIB_META, "Meta TableFiles schema is created by Milvus old version");
}
}
Status
SqliteMetaImpl::Initialize() {
if (!boost::filesystem::is_directory(options_.path_)) {
@ -158,6 +227,14 @@ SqliteMetaImpl::Initialize() {
ConnectorPtr->open_forever(); // thread safe option
ConnectorPtr->pragma.journal_mode(journal_mode::WAL); // WAL => write ahead log
CollectionConnectPtr = std::make_unique<CollectionConnectT>(CollectionPrototype(options_.path_ + "/metah.sqlite"));
ValidateCollectionMetaSchema();
CollectionConnectPtr->sync_schema();
CollectionConnectPtr->open_forever();
CollectionConnectPtr->pragma.journal_mode(journal_mode::WAL); // WAL => write ahead log
CleanUpShadowFiles();
return Status::OK();
@ -1772,6 +1849,176 @@ SqliteMetaImpl::GetGlobalLastLSN(uint64_t& lsn) {
return Status::OK();
}
Status
SqliteMetaImpl::CreateHybridCollection(meta::CollectionSchema& collection_schema,
meta::hybrid::FieldsSchema& fields_schema) {
try {
server::MetricCollector metric;
// multi-threads call sqlite update may get exception('bad logic', etc), so we add a lock here
std::lock_guard<std::mutex> meta_lock(meta_mutex_);
if (collection_schema.collection_id_ == "") {
NextCollectionId(collection_schema.collection_id_);
} else {
fiu_do_on("SqliteMetaImpl.CreateCollection.throw_exception", throw std::exception());
auto collection = ConnectorPtr->select(columns(&CollectionSchema::state_),
where(c(&CollectionSchema::collection_id_)
== collection_schema.collection_id_));
if (collection.size() == 1) {
if (CollectionSchema::TO_DELETE == std::get<0>(collection[0])) {
return Status(DB_ERROR, "Collection already exists and it is in delete state, please wait a second");
} else {
// Change from no error to already exist.
return Status(DB_ALREADY_EXIST, "Collection already exists");
}
}
}
collection_schema.id_ = -1;
collection_schema.created_on_ = utils::GetMicroSecTimeStamp();
try {
fiu_do_on("SqliteMetaImpl.CreateHybridCollection.insert_throw_exception", throw std::exception());
auto id = ConnectorPtr->insert(collection_schema);
collection_schema.id_ = id;
} catch (std::exception& e) {
return HandleException("Encounter exception when create collection", e.what());
}
LOG_ENGINE_DEBUG_ << "Successfully create collection collection: " << collection_schema.collection_id_;
Status status = utils::CreateCollectionPath(options_, collection_schema.collection_id_);
if (!status.ok()) {
return status;
}
try {
for (uint64_t i = 0; i < fields_schema.fields_schema_.size(); ++i) {
hybrid::FieldSchema schema = fields_schema.fields_schema_[i];
auto field_id = ConnectorPtr->insert(schema);
LOG_ENGINE_DEBUG_ << "Successfully create collection field" << field_id;
}
} catch (std::exception& e) {
return HandleException("Encounter exception when create collection field", e.what());
}
return status;
} catch (std::exception& e) {
return HandleException("Encounter exception when create collection", e.what());
}
}
Status
SqliteMetaImpl::DescribeHybridCollection(milvus::engine::meta::CollectionSchema& collection_schema,
milvus::engine::meta::hybrid::FieldsSchema& fields_schema) {
try {
server::MetricCollector metric;
fiu_do_on("SqliteMetaImpl.DescriCollection.throw_exception", throw std::exception());
auto groups = ConnectorPtr->select(
columns(&CollectionSchema::id_, &CollectionSchema::state_, &CollectionSchema::dimension_, &CollectionSchema::created_on_,
&CollectionSchema::flag_, &CollectionSchema::index_file_size_, &CollectionSchema::engine_type_,
&CollectionSchema::index_params_, &CollectionSchema::metric_type_, &CollectionSchema::owner_collection_,
&CollectionSchema::partition_tag_, &CollectionSchema::version_, &CollectionSchema::flush_lsn_),
where(c(&CollectionSchema::collection_id_) == collection_schema.collection_id_ and
c(&CollectionSchema::state_) != (int)CollectionSchema::TO_DELETE));
if (groups.size() == 1) {
collection_schema.id_ = std::get<0>(groups[0]);
collection_schema.state_ = std::get<1>(groups[0]);
collection_schema.dimension_ = std::get<2>(groups[0]);
collection_schema.created_on_ = std::get<3>(groups[0]);
collection_schema.flag_ = std::get<4>(groups[0]);
collection_schema.index_file_size_ = std::get<5>(groups[0]);
collection_schema.engine_type_ = std::get<6>(groups[0]);
collection_schema.index_params_ = std::get<7>(groups[0]);
collection_schema.metric_type_ = std::get<8>(groups[0]);
collection_schema.owner_collection_ = std::get<9>(groups[0]);
collection_schema.partition_tag_ = std::get<10>(groups[0]);
collection_schema.version_ = std::get<11>(groups[0]);
collection_schema.flush_lsn_ = std::get<12>(groups[0]);
} else {
return Status(DB_NOT_FOUND, "Collection " + collection_schema.collection_id_ + " not found");
}
auto field_groups = ConnectorPtr->select(
columns(&hybrid::FieldSchema::collection_id_,
&hybrid::FieldSchema::field_name_,
&hybrid::FieldSchema::field_type_,
&hybrid::FieldSchema::field_params_),
where(c(&hybrid::FieldSchema::collection_id_) == collection_schema.collection_id_));
if (field_groups.size() >= 1) {
fields_schema.fields_schema_.resize(field_groups.size());
for (uint64_t i = 0; i < field_groups.size(); ++i) {
fields_schema.fields_schema_[i].collection_id_ = std::get<0>(field_groups[i]);
fields_schema.fields_schema_[i].field_name_ = std::get<1>(field_groups[i]);
fields_schema.fields_schema_[i].field_type_ = std::get<2>(field_groups[i]);
fields_schema.fields_schema_[i].field_params_ = std::get<3>(field_groups[i]);
}
} else {
return Status(DB_NOT_FOUND, "Collection " + collection_schema.collection_id_ + " fields not found");
}
} catch (std::exception& e) {
return HandleException("Encounter exception when describe collection", e.what());
}
return Status::OK();
}
Status
SqliteMetaImpl::CreateHybridCollectionFile(SegmentSchema& file_schema) {
if (file_schema.date_ == EmptyDate) {
file_schema.date_ = utils::GetDate();
}
CollectionSchema collection_schema;
hybrid::FieldsSchema fields_schema;
collection_schema.collection_id_ = file_schema.collection_id_;
auto status = DescribeHybridCollection(collection_schema, fields_schema);
if (!status.ok()) {
return status;
}
try {
fiu_do_on("SqliteMetaImpl.CreateCollectionFile.throw_exception", throw std::exception());
server::MetricCollector metric;
NextFileId(file_schema.file_id_);
if (file_schema.segment_id_.empty()) {
file_schema.segment_id_ = file_schema.file_id_;
}
file_schema.dimension_ = collection_schema.dimension_;
file_schema.file_size_ = 0;
file_schema.row_count_ = 0;
file_schema.created_on_ = utils::GetMicroSecTimeStamp();
file_schema.updated_time_ = file_schema.created_on_;
file_schema.index_file_size_ = collection_schema.index_file_size_;
file_schema.index_params_ = collection_schema.index_params_;
file_schema.engine_type_ = collection_schema.engine_type_;
file_schema.metric_type_ = collection_schema.metric_type_;
// multi-threads call sqlite update may get exception('bad logic', etc), so we add a lock here
std::lock_guard<std::mutex> meta_lock(meta_mutex_);
auto id = ConnectorPtr->insert(file_schema);
file_schema.id_ = id;
for (auto field_schema : fields_schema.fields_schema_) {
ConnectorPtr->insert(field_schema);
}
LOG_ENGINE_DEBUG_ << "Successfully create collection file, file id = " << file_schema.file_id_;
return utils::CreateCollectionFilePath(options_, file_schema);
} catch (std::exception& e) {
return HandleException("Encounter exception when create collection file", e.what());
}
return Status::OK();
}
} // namespace meta
} // namespace engine
} // namespace milvus

View File

@ -25,6 +25,9 @@ namespace meta {
auto
StoragePrototype(const std::string& path);
auto
CollectionPrototype(const std::string& path);
class SqliteMetaImpl : public Meta {
public:
explicit SqliteMetaImpl(const DBMetaOptions& options);
@ -141,6 +144,15 @@ class SqliteMetaImpl : public Meta {
Status
GetGlobalLastLSN(uint64_t& lsn) override;
Status
CreateHybridCollection(CollectionSchema& collection_schema, hybrid::FieldsSchema& fields_schema) override;
Status
DescribeHybridCollection(CollectionSchema& collection_schema, hybrid::FieldsSchema& fields_schema) override;
Status
CreateHybridCollectionFile(SegmentSchema& file_schema) override;
private:
Status
NextFileId(std::string& file_id);
@ -151,6 +163,8 @@ class SqliteMetaImpl : public Meta {
void
ValidateMetaSchema();
void
ValidateCollectionMetaSchema();
Status
Initialize();

View File

@ -14,6 +14,7 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "db/Types.h"
#include "db/meta/MetaTypes.h"
@ -23,12 +24,12 @@ namespace engine {
namespace wal {
using TableSchemaPtr = std::shared_ptr<milvus::engine::meta::CollectionSchema>;
using TableMetaPtr = std::shared_ptr<std::unordered_map<std::string, TableSchemaPtr> >;
using TableMetaPtr = std::shared_ptr<std::unordered_map<std::string, TableSchemaPtr>>;
#define UNIT_MB (1024 * 1024)
#define LSN_OFFSET_MASK 0x00000000ffffffff
enum class MXLogType { InsertBinary, InsertVector, Delete, Update, Flush, None };
enum class MXLogType { InsertBinary, InsertVector, Delete, Update, Flush, None, Entity };
struct MXLogRecord {
uint64_t lsn;
@ -39,6 +40,9 @@ struct MXLogRecord {
const IDNumber* ids;
uint32_t data_size;
const void* data;
std::unordered_map<std::string, uint64_t> attr_nbytes;
std::unordered_map<std::string, uint64_t> attr_data_size;
std::unordered_map<std::string, std::vector<uint8_t>> attr_data;
};
struct MXLogConfiguration {

View File

@ -44,6 +44,20 @@ static const char* MilvusService_method_names[] = {
"/milvus.grpc.MilvusService/PreloadCollection",
"/milvus.grpc.MilvusService/Flush",
"/milvus.grpc.MilvusService/Compact",
"/milvus.grpc.MilvusService/CreateHybridCollection",
"/milvus.grpc.MilvusService/HasHybridCollection",
"/milvus.grpc.MilvusService/DropHybridCollection",
"/milvus.grpc.MilvusService/DescribeHybridCollection",
"/milvus.grpc.MilvusService/CountHybridCollection",
"/milvus.grpc.MilvusService/ShowHybridCollections",
"/milvus.grpc.MilvusService/ShowHybridCollectionInfo",
"/milvus.grpc.MilvusService/PreloadHybridCollection",
"/milvus.grpc.MilvusService/InsertEntity",
"/milvus.grpc.MilvusService/HybridSearch",
"/milvus.grpc.MilvusService/HybridSearchInSegments",
"/milvus.grpc.MilvusService/GetEntityByID",
"/milvus.grpc.MilvusService/GetEntityIDs",
"/milvus.grpc.MilvusService/DeleteEntitiesByID",
};
std::unique_ptr< MilvusService::Stub> MilvusService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
@ -77,6 +91,20 @@ MilvusService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& chan
, rpcmethod_PreloadCollection_(MilvusService_method_names[21], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Flush_(MilvusService_method_names[22], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Compact_(MilvusService_method_names[23], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CreateHybridCollection_(MilvusService_method_names[24], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HasHybridCollection_(MilvusService_method_names[25], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DropHybridCollection_(MilvusService_method_names[26], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DescribeHybridCollection_(MilvusService_method_names[27], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CountHybridCollection_(MilvusService_method_names[28], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowHybridCollections_(MilvusService_method_names[29], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowHybridCollectionInfo_(MilvusService_method_names[30], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_PreloadHybridCollection_(MilvusService_method_names[31], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_InsertEntity_(MilvusService_method_names[32], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HybridSearch_(MilvusService_method_names[33], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HybridSearchInSegments_(MilvusService_method_names[34], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetEntityByID_(MilvusService_method_names[35], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetEntityIDs_(MilvusService_method_names[36], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DeleteEntitiesByID_(MilvusService_method_names[37], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
{}
::grpc::Status MilvusService::Stub::CreateCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionSchema& request, ::milvus::grpc::Status* response) {
@ -751,6 +779,398 @@ void MilvusService::Stub::experimental_async::Compact(::grpc::ClientContext* con
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_Compact_, context, request, false);
}
::grpc::Status MilvusService::Stub::CreateHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::Mapping& request, ::milvus::grpc::Status* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_CreateHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::CreateHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::Mapping* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_CreateHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::CreateHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_CreateHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::CreateHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::Mapping* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_CreateHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::CreateHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_CreateHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::AsyncCreateHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::Mapping& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_CreateHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::PrepareAsyncCreateHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::Mapping& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_CreateHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::HasHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::BoolReply* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_HasHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::HasHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::BoolReply* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HasHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HasHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::BoolReply* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HasHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HasHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::BoolReply* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HasHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::HasHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::BoolReply* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HasHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::BoolReply>* MilvusService::Stub::AsyncHasHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::BoolReply>::Create(channel_.get(), cq, rpcmethod_HasHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::BoolReply>* MilvusService::Stub::PrepareAsyncHasHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::BoolReply>::Create(channel_.get(), cq, rpcmethod_HasHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::DropHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::Status* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_DropHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::DropHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DropHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DropHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DropHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DropHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DropHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::DropHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DropHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::AsyncDropHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_DropHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::PrepareAsyncDropHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_DropHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::DescribeHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::Mapping* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_DescribeHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::DescribeHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Mapping* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DescribeHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DescribeHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Mapping* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DescribeHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DescribeHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Mapping* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DescribeHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::DescribeHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Mapping* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DescribeHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Mapping>* MilvusService::Stub::AsyncDescribeHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Mapping>::Create(channel_.get(), cq, rpcmethod_DescribeHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Mapping>* MilvusService::Stub::PrepareAsyncDescribeHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Mapping>::Create(channel_.get(), cq, rpcmethod_DescribeHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::CountHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::CollectionRowCount* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_CountHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::CountHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionRowCount* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_CountHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::CountHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::CollectionRowCount* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_CountHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::CountHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionRowCount* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_CountHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::CountHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::CollectionRowCount* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_CountHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::CollectionRowCount>* MilvusService::Stub::AsyncCountHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::CollectionRowCount>::Create(channel_.get(), cq, rpcmethod_CountHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::CollectionRowCount>* MilvusService::Stub::PrepareAsyncCountHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::CollectionRowCount>::Create(channel_.get(), cq, rpcmethod_CountHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::ShowHybridCollections(::grpc::ClientContext* context, const ::milvus::grpc::Command& request, ::milvus::grpc::MappingList* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_ShowHybridCollections_, context, request, response);
}
void MilvusService::Stub::experimental_async::ShowHybridCollections(::grpc::ClientContext* context, const ::milvus::grpc::Command* request, ::milvus::grpc::MappingList* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollections_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::ShowHybridCollections(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::MappingList* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollections_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::ShowHybridCollections(::grpc::ClientContext* context, const ::milvus::grpc::Command* request, ::milvus::grpc::MappingList* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollections_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::ShowHybridCollections(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::MappingList* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollections_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::MappingList>* MilvusService::Stub::AsyncShowHybridCollectionsRaw(::grpc::ClientContext* context, const ::milvus::grpc::Command& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::MappingList>::Create(channel_.get(), cq, rpcmethod_ShowHybridCollections_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::MappingList>* MilvusService::Stub::PrepareAsyncShowHybridCollectionsRaw(::grpc::ClientContext* context, const ::milvus::grpc::Command& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::MappingList>::Create(channel_.get(), cq, rpcmethod_ShowHybridCollections_, context, request, false);
}
::grpc::Status MilvusService::Stub::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::CollectionInfo* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_ShowHybridCollectionInfo_, context, request, response);
}
void MilvusService::Stub::experimental_async::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionInfo* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollectionInfo_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::CollectionInfo* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollectionInfo_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionInfo* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollectionInfo_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::CollectionInfo* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollectionInfo_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::CollectionInfo>* MilvusService::Stub::AsyncShowHybridCollectionInfoRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::CollectionInfo>::Create(channel_.get(), cq, rpcmethod_ShowHybridCollectionInfo_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::CollectionInfo>* MilvusService::Stub::PrepareAsyncShowHybridCollectionInfoRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::CollectionInfo>::Create(channel_.get(), cq, rpcmethod_ShowHybridCollectionInfo_, context, request, false);
}
::grpc::Status MilvusService::Stub::PreloadHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::Status* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_PreloadHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::PreloadHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_PreloadHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::PreloadHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_PreloadHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::PreloadHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_PreloadHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::PreloadHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_PreloadHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::AsyncPreloadHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_PreloadHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::PrepareAsyncPreloadHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_PreloadHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::InsertEntity(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam& request, ::milvus::grpc::HEntityIDs* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_InsertEntity_, context, request, response);
}
void MilvusService::Stub::experimental_async::InsertEntity(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam* request, ::milvus::grpc::HEntityIDs* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_InsertEntity_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::InsertEntity(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntityIDs* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_InsertEntity_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::InsertEntity(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam* request, ::milvus::grpc::HEntityIDs* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_InsertEntity_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::InsertEntity(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntityIDs* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_InsertEntity_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntityIDs>* MilvusService::Stub::AsyncInsertEntityRaw(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntityIDs>::Create(channel_.get(), cq, rpcmethod_InsertEntity_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntityIDs>* MilvusService::Stub::PrepareAsyncInsertEntityRaw(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntityIDs>::Create(channel_.get(), cq, rpcmethod_InsertEntity_, context, request, false);
}
::grpc::Status MilvusService::Stub::HybridSearch(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam& request, ::milvus::grpc::TopKQueryResult* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_HybridSearch_, context, request, response);
}
void MilvusService::Stub::experimental_async::HybridSearch(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam* request, ::milvus::grpc::TopKQueryResult* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HybridSearch_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HybridSearch(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::TopKQueryResult* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HybridSearch_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HybridSearch(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam* request, ::milvus::grpc::TopKQueryResult* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HybridSearch_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::HybridSearch(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::TopKQueryResult* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HybridSearch_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::TopKQueryResult>* MilvusService::Stub::AsyncHybridSearchRaw(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::TopKQueryResult>::Create(channel_.get(), cq, rpcmethod_HybridSearch_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::TopKQueryResult>* MilvusService::Stub::PrepareAsyncHybridSearchRaw(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::TopKQueryResult>::Create(channel_.get(), cq, rpcmethod_HybridSearch_, context, request, false);
}
::grpc::Status MilvusService::Stub::HybridSearchInSegments(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam& request, ::milvus::grpc::TopKQueryResult* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_HybridSearchInSegments_, context, request, response);
}
void MilvusService::Stub::experimental_async::HybridSearchInSegments(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam* request, ::milvus::grpc::TopKQueryResult* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HybridSearchInSegments_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HybridSearchInSegments(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::TopKQueryResult* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HybridSearchInSegments_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HybridSearchInSegments(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam* request, ::milvus::grpc::TopKQueryResult* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HybridSearchInSegments_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::HybridSearchInSegments(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::TopKQueryResult* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HybridSearchInSegments_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::TopKQueryResult>* MilvusService::Stub::AsyncHybridSearchInSegmentsRaw(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::TopKQueryResult>::Create(channel_.get(), cq, rpcmethod_HybridSearchInSegments_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::TopKQueryResult>* MilvusService::Stub::PrepareAsyncHybridSearchInSegmentsRaw(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::TopKQueryResult>::Create(channel_.get(), cq, rpcmethod_HybridSearchInSegments_, context, request, false);
}
::grpc::Status MilvusService::Stub::GetEntityByID(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity& request, ::milvus::grpc::HEntity* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetEntityByID_, context, request, response);
}
void MilvusService::Stub::experimental_async::GetEntityByID(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity* request, ::milvus::grpc::HEntity* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetEntityByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetEntityByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntity* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetEntityByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetEntityByID(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity* request, ::milvus::grpc::HEntity* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetEntityByID_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::GetEntityByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntity* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetEntityByID_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntity>* MilvusService::Stub::AsyncGetEntityByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntity>::Create(channel_.get(), cq, rpcmethod_GetEntityByID_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntity>* MilvusService::Stub::PrepareAsyncGetEntityByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntity>::Create(channel_.get(), cq, rpcmethod_GetEntityByID_, context, request, false);
}
::grpc::Status MilvusService::Stub::GetEntityIDs(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam& request, ::milvus::grpc::HEntityIDs* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetEntityIDs_, context, request, response);
}
void MilvusService::Stub::experimental_async::GetEntityIDs(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam* request, ::milvus::grpc::HEntityIDs* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetEntityIDs_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetEntityIDs(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntityIDs* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetEntityIDs_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetEntityIDs(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam* request, ::milvus::grpc::HEntityIDs* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetEntityIDs_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::GetEntityIDs(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntityIDs* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetEntityIDs_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntityIDs>* MilvusService::Stub::AsyncGetEntityIDsRaw(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntityIDs>::Create(channel_.get(), cq, rpcmethod_GetEntityIDs_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntityIDs>* MilvusService::Stub::PrepareAsyncGetEntityIDsRaw(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntityIDs>::Create(channel_.get(), cq, rpcmethod_GetEntityIDs_, context, request, false);
}
::grpc::Status MilvusService::Stub::DeleteEntitiesByID(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam& request, ::milvus::grpc::Status* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_DeleteEntitiesByID_, context, request, response);
}
void MilvusService::Stub::experimental_async::DeleteEntitiesByID(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DeleteEntitiesByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DeleteEntitiesByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DeleteEntitiesByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DeleteEntitiesByID(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DeleteEntitiesByID_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::DeleteEntitiesByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DeleteEntitiesByID_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::AsyncDeleteEntitiesByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_DeleteEntitiesByID_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::PrepareAsyncDeleteEntitiesByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_DeleteEntitiesByID_, context, request, false);
}
MilvusService::Service::Service() {
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[0],
@ -872,6 +1292,76 @@ MilvusService::Service::Service() {
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::Compact), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[24],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::Mapping, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::CreateHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[25],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::BoolReply>(
std::mem_fn(&MilvusService::Service::HasHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[26],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::DropHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[27],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Mapping>(
std::mem_fn(&MilvusService::Service::DescribeHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[28],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::CollectionRowCount>(
std::mem_fn(&MilvusService::Service::CountHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[29],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::Command, ::milvus::grpc::MappingList>(
std::mem_fn(&MilvusService::Service::ShowHybridCollections), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[30],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::CollectionInfo>(
std::mem_fn(&MilvusService::Service::ShowHybridCollectionInfo), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[31],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::PreloadHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[32],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HInsertParam, ::milvus::grpc::HEntityIDs>(
std::mem_fn(&MilvusService::Service::InsertEntity), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[33],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HSearchParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::HybridSearch), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[34],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HSearchInSegmentsParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::HybridSearchInSegments), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[35],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HEntityIdentity, ::milvus::grpc::HEntity>(
std::mem_fn(&MilvusService::Service::GetEntityByID), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[36],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HGetEntityIDsParam, ::milvus::grpc::HEntityIDs>(
std::mem_fn(&MilvusService::Service::GetEntityIDs), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[37],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HDeleteByIDParam, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::DeleteEntitiesByID), this)));
}
MilvusService::Service::~Service() {
@ -1045,6 +1535,104 @@ MilvusService::Service::~Service() {
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::CreateHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::Mapping* request, ::milvus::grpc::Status* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::HasHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::BoolReply* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::DropHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::DescribeHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Mapping* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::CountHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionRowCount* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::ShowHybridCollections(::grpc::ServerContext* context, const ::milvus::grpc::Command* request, ::milvus::grpc::MappingList* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::ShowHybridCollectionInfo(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionInfo* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::PreloadHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::InsertEntity(::grpc::ServerContext* context, const ::milvus::grpc::HInsertParam* request, ::milvus::grpc::HEntityIDs* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::HybridSearch(::grpc::ServerContext* context, const ::milvus::grpc::HSearchParam* request, ::milvus::grpc::TopKQueryResult* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::HybridSearchInSegments(::grpc::ServerContext* context, const ::milvus::grpc::HSearchInSegmentsParam* request, ::milvus::grpc::TopKQueryResult* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::GetEntityByID(::grpc::ServerContext* context, const ::milvus::grpc::HEntityIdentity* request, ::milvus::grpc::HEntity* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::GetEntityIDs(::grpc::ServerContext* context, const ::milvus::grpc::HGetEntityIDsParam* request, ::milvus::grpc::HEntityIDs* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::DeleteEntitiesByID(::grpc::ServerContext* context, const ::milvus::grpc::HDeleteByIDParam* request, ::milvus::grpc::Status* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
} // namespace milvus
} // namespace grpc

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -232,6 +232,208 @@ message GetVectorIDsParam {
string segment_name = 2;
}
/********************************************************************************************************************/
enum DataType {
NULL = 0;
INT8 = 1;
INT16 = 2;
INT32 = 3;
INT64 = 4;
STRING = 20;
BOOL = 30;
FLOAT = 40;
DOUBLE = 41;
VECTOR = 100;
UNKNOWN = 9999;
}
///////////////////////////////////////////////////////////////////
message VectorFieldParam {
int64 dimension = 1;
}
message FieldType {
oneof value {
DataType data_type = 1;
VectorFieldParam vector_param = 2;
}
}
message FieldParam {
uint64 id = 1;
string name = 2;
FieldType type = 3;
repeated KeyValuePair extra_params = 4;
}
message VectorFieldValue {
repeated RowRecord value = 1;
}
message FieldValue {
oneof value {
int32 int32_value = 1;
int64 int64_value = 2;
float float_value = 3;
double double_value = 4;
string string_value = 5;
bool bool_value = 6;
VectorFieldValue vector_value = 7;
}
}
///////////////////////////////////////////////////////////////////
message Mapping {
Status status = 1;
uint64 collection_id = 2;
string collection_name = 3;
repeated FieldParam fields = 4;
}
message MappingList {
Status status = 1;
repeated Mapping mapping_list = 2;
}
///////////////////////////////////////////////////////////////////
message TermQuery {
string field_name = 1;
repeated string values = 2;
float boost = 3;
repeated KeyValuePair extra_params = 4;
}
enum CompareOperator {
LT = 0;
LTE = 1;
EQ = 2;
GT = 3;
GTE = 4;
NE = 5;
}
message CompareExpr {
CompareOperator operator = 1;
string operand = 2;
}
message RangeQuery {
string field_name = 1;
repeated CompareExpr operand = 2;
float boost = 3;
repeated KeyValuePair extra_params = 4;
}
message VectorQuery {
string field_name = 1;
float query_boost = 2;
repeated RowRecord records = 3;
int64 topk = 4;
repeated KeyValuePair extra_params = 5;
}
enum Occur {
INVALID = 0;
MUST = 1;
SHOULD = 2;
MUST_NOT = 3;
}
message BooleanQuery {
Occur occur = 1;
repeated GeneralQuery general_query = 2;
}
message GeneralQuery {
oneof query {
BooleanQuery boolean_query = 1;
TermQuery term_query = 2;
RangeQuery range_query = 3;
VectorQuery vector_query = 4;
}
}
message HSearchParam {
string collection_name = 1;
repeated string partition_tag_array = 2;
GeneralQuery general_query = 3;
repeated KeyValuePair extra_params = 4;
}
message HSearchInSegmentsParam {
repeated string segment_id_array = 1;
HSearchParam search_param = 2;
}
///////////////////////////////////////////////////////////////////
message AttrRecord {
repeated string value = 1;
}
message HEntity {
Status status = 1;
int64 entity_id = 2;
repeated string field_names = 3;
repeated AttrRecord attr_records = 4;
repeated FieldValue result_values = 5;
}
message HQueryResult {
Status status = 1;
repeated HEntity entities = 2;
int64 row_num = 3;
repeated float score = 4;
repeated float distance = 5;
}
message HInsertParam {
string collection_name = 1;
string partition_tag = 2;
HEntity entities = 3;
repeated int64 entity_id_array = 4;
repeated KeyValuePair extra_params = 5;
}
message HEntityIdentity {
string collection_name = 1;
int64 id = 2;
}
message HEntityIDs {
Status status = 1;
repeated int64 entity_id_array = 2;
}
message HGetEntityIDsParam {
string collection_name = 1;
string segment_name = 2;
}
message HDeleteByIDParam {
string collection_name = 1;
repeated int64 id_array = 2;
}
///////////////////////////////////////////////////////////////////
message HIndexParam {
Status status = 1;
string collection_name = 2;
int32 index_type = 3;
repeated KeyValuePair extra_params = 4;
}
service MilvusService {
/**
* @brief This method is used to create collection
@ -448,4 +650,47 @@ service MilvusService {
* @return Status
*/
rpc Compact(CollectionName) returns (Status) {}
}
/********************************New Interface********************************************/
rpc CreateHybridCollection(Mapping) returns (Status) {}
rpc HasHybridCollection(CollectionName) returns (BoolReply) {}
rpc DropHybridCollection(CollectionName) returns (Status) {}
rpc DescribeHybridCollection(CollectionName) returns (Mapping) {}
rpc CountHybridCollection(CollectionName) returns (CollectionRowCount) {}
rpc ShowHybridCollections(Command) returns (MappingList) {}
rpc ShowHybridCollectionInfo (CollectionName) returns (CollectionInfo) {}
rpc PreloadHybridCollection(CollectionName) returns (Status) {}
///////////////////////////////////////////////////////////////////
// rpc CreateIndex(IndexParam) returns (Status) {}
//
// rpc DescribeIndex(CollectionName) returns (IndexParam) {}
//
// rpc DropIndex(CollectionName) returns (Status) {}
///////////////////////////////////////////////////////////////////
rpc InsertEntity(HInsertParam) returns (HEntityIDs) {}
// TODO(yukun): will change to HQueryResult
rpc HybridSearch(HSearchParam) returns (TopKQueryResult) {}
rpc HybridSearchInSegments(HSearchInSegmentsParam) returns (TopKQueryResult) {}
rpc GetEntityByID(HEntityIdentity) returns (HEntity) {}
rpc GetEntityIDs(HGetEntityIDsParam) returns (HEntityIDs) {}
rpc DeleteEntitiesByID(HDeleteByIDParam) returns (Status) {}
///////////////////////////////////////////////////////////////////
}

View File

@ -0,0 +1,222 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "query/BinaryQuery.h"
namespace milvus {
namespace query {
BinaryQueryPtr
ConstructBinTree(std::vector<BooleanQueryPtr> queries, QueryRelation relation, uint64_t idx) {
if (idx == queries.size()) {
return nullptr;
} else if (idx == queries.size() - 1) {
return queries[idx]->getBinaryQuery();
} else {
BinaryQueryPtr bquery = std::make_shared<BinaryQuery>();
bquery->relation = relation;
bquery->left_query = std::make_shared<GeneralQuery>();
bquery->right_query = std::make_shared<GeneralQuery>();
bquery->left_query->bin = queries[idx]->getBinaryQuery();
++idx;
bquery->right_query->bin = ConstructBinTree(queries, relation, idx);
return bquery;
}
}
Status
ConstructLeafBinTree(std::vector<LeafQueryPtr> leaf_queries, BinaryQueryPtr binary_query, uint64_t idx) {
if (idx == leaf_queries.size()) {
return Status::OK();
}
binary_query->left_query = std::make_shared<GeneralQuery>();
binary_query->right_query = std::make_shared<GeneralQuery>();
if (leaf_queries.size() == leaf_queries.size() - 1) {
binary_query->left_query->leaf = leaf_queries[idx];
return Status::OK();
} else if (idx == leaf_queries.size() - 2) {
binary_query->left_query->leaf = leaf_queries[idx];
++idx;
binary_query->right_query->leaf = leaf_queries[idx];
return Status::OK();
} else {
binary_query->left_query->bin->relation = binary_query->relation;
binary_query->right_query->leaf = leaf_queries[idx];
++idx;
return ConstructLeafBinTree(leaf_queries, binary_query->left_query->bin, idx);
}
}
Status
GenBinaryQuery(BooleanQueryPtr query, BinaryQueryPtr& binary_query) {
if (query->getBooleanQuerys().size() == 0) {
if (binary_query->relation == QueryRelation::AND || binary_query->relation == QueryRelation::OR) {
// Put VectorQuery to the end of leafqueries
auto query_size = query->getLeafQueries().size();
for (uint64_t i = 0; i < query_size; ++i) {
if (query->getLeafQueries()[i]->vector_query != nullptr) {
std::swap(query->getLeafQueries()[i], query->getLeafQueries()[0]);
break;
}
}
return ConstructLeafBinTree(query->getLeafQueries(), binary_query, 0);
} else {
switch (query->getOccur()) {
case Occur::MUST: {
binary_query->relation = QueryRelation::AND;
return GenBinaryQuery(query, binary_query);
}
case Occur::MUST_NOT:
case Occur::SHOULD: {
binary_query->relation = QueryRelation::OR;
return GenBinaryQuery(query, binary_query);
}
}
}
}
if (query->getBooleanQuerys().size() == 1) {
auto bc = query->getBooleanQuerys()[0];
binary_query->left_query = std::make_shared<GeneralQuery>();
switch (bc->getOccur()) {
case Occur::MUST: {
binary_query->relation = QueryRelation::AND;
Status s = GenBinaryQuery(bc, binary_query);
return s;
}
case Occur::MUST_NOT:
case Occur::SHOULD: {
binary_query->relation = QueryRelation::OR;
Status s = GenBinaryQuery(bc, binary_query);
return s;
}
}
}
// Construct binary query for every single boolean query
std::vector<BooleanQueryPtr> must_queries;
std::vector<BooleanQueryPtr> must_not_queries;
std::vector<BooleanQueryPtr> should_queries;
Status status;
for (auto& _query : query->getBooleanQuerys()) {
status = GenBinaryQuery(_query, _query->getBinaryQuery());
if (!status.ok()) {
return status;
}
if (_query->getOccur() == Occur::MUST) {
must_queries.emplace_back(_query);
} else if (_query->getOccur() == Occur::MUST_NOT) {
must_not_queries.emplace_back(_query);
} else {
should_queries.emplace_back(_query);
}
}
// Construct binary query for combine boolean queries
BinaryQueryPtr must_bquery, should_bquery, must_not_bquery;
uint64_t bquery_num = 0;
if (must_queries.size() > 1) {
// Construct a must binary tree
must_bquery = ConstructBinTree(must_queries, QueryRelation::R1, 0);
++bquery_num;
} else if (must_queries.size() == 1) {
must_bquery = must_queries[0]->getBinaryQuery();
++bquery_num;
}
if (should_queries.size() > 1) {
// Construct a should binary tree
should_bquery = ConstructBinTree(should_queries, QueryRelation::R2, 0);
++bquery_num;
} else if (should_queries.size() == 1) {
should_bquery = should_queries[0]->getBinaryQuery();
++bquery_num;
}
if (must_not_queries.size() > 1) {
// Construct a must_not binary tree
must_not_bquery = ConstructBinTree(must_not_queries, QueryRelation::R1, 0);
++bquery_num;
} else if (must_not_queries.size() == 1) {
must_not_bquery = must_not_queries[0]->getBinaryQuery();
++bquery_num;
}
binary_query->left_query = std::make_shared<GeneralQuery>();
binary_query->right_query = std::make_shared<GeneralQuery>();
BinaryQueryPtr must_should_query = std::make_shared<BinaryQuery>();
must_should_query->left_query = std::make_shared<GeneralQuery>();
must_should_query->right_query = std::make_shared<GeneralQuery>();
if (bquery_num == 3) {
must_should_query->relation = QueryRelation::R3;
must_should_query->left_query->bin = must_bquery;
must_should_query->right_query->bin = should_bquery;
binary_query->relation = QueryRelation::R1;
binary_query->left_query->bin = must_should_query;
binary_query->right_query->bin = must_not_bquery;
} else if (bquery_num == 2) {
if (must_bquery == nullptr) {
binary_query->relation = QueryRelation::R3;
binary_query->left_query->bin = must_not_bquery;
binary_query->right_query->bin = should_bquery;
} else if (should_bquery == nullptr) {
binary_query->relation = QueryRelation::R4;
binary_query->left_query->bin = must_bquery;
binary_query->right_query->bin = must_not_bquery;
} else {
binary_query->relation = QueryRelation::R3;
binary_query->left_query->bin = must_bquery;
binary_query->right_query->bin = should_bquery;
}
} else {
if (must_bquery != nullptr) {
binary_query = must_bquery;
} else if (should_bquery != nullptr) {
binary_query = should_bquery;
} else {
binary_query = must_not_bquery;
}
}
return Status::OK();
}
uint64_t
BinaryQueryHeight(BinaryQueryPtr& binary_query) {
if (binary_query == nullptr) {
return 1;
}
uint64_t left_height = 0, right_height = 0;
if (binary_query->left_query != nullptr) {
left_height = BinaryQueryHeight(binary_query->left_query->bin);
}
if (binary_query->right_query != nullptr) {
right_height = BinaryQueryHeight(binary_query->right_query->bin);
}
return left_height > right_height ? left_height + 1 : right_height + 1;
}
bool
ValidateBinaryQuery(BinaryQueryPtr& binary_query) {
// Only for one layer BooleanQuery
uint64_t height = BinaryQueryHeight(binary_query);
return height > 1 && height < 4;
}
} // namespace query
} // namespace milvus

View File

@ -0,0 +1,38 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <memory>
#include <vector>
#include "BooleanQuery.h"
namespace milvus {
namespace query {
BinaryQueryPtr
ConstructBinTree(std::vector<BooleanQueryPtr> clauses, QueryRelation relation, uint64_t idx);
Status
ConstructLeafBinTree(std::vector<LeafQueryPtr> leaf_clauses, BinaryQueryPtr binary_query, uint64_t idx);
Status
GenBinaryQuery(BooleanQueryPtr clause, BinaryQueryPtr& binary_query);
uint64_t
BinaryQueryHeight(BinaryQueryPtr& binary_query);
bool
ValidateBinaryQuery(BinaryQueryPtr& binary_query);
} // namespace query
} // namespace milvus

View File

@ -0,0 +1,87 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <memory>
#include <vector>
#include "GeneralQuery.h"
#include "utils/Status.h"
namespace milvus {
namespace query {
enum class Occur {
INVALID = 0,
MUST,
MUST_NOT,
SHOULD,
};
class BooleanQuery {
public:
BooleanQuery() {
}
explicit BooleanQuery(Occur occur) : occur_(occur) {
}
Occur
getOccur() {
return occur_;
}
void
SetOccur(Occur occur) {
occur_ = occur;
}
void
AddBooleanQuery(std::shared_ptr<BooleanQuery> boolean_clause) {
boolean_clauses_.emplace_back(boolean_clause);
}
void
AddLeafQuery(LeafQueryPtr leaf_query) {
leaf_queries_.emplace_back(leaf_query);
}
void
SetLeafQuery(std::vector<LeafQueryPtr> leaf_queries) {
leaf_queries_ = leaf_queries;
}
std::vector<std::shared_ptr<BooleanQuery>>
getBooleanQuerys() {
return boolean_clauses_;
}
BinaryQueryPtr&
getBinaryQuery() {
return binary_query_;
}
std::vector<LeafQueryPtr>&
getLeafQueries() {
return leaf_queries_;
}
private:
Occur occur_ = Occur::INVALID;
std::vector<std::shared_ptr<BooleanQuery>> boolean_clauses_;
std::vector<LeafQueryPtr> leaf_queries_;
BinaryQueryPtr binary_query_ = std::make_shared<BinaryQuery>();
};
using BooleanQueryPtr = std::shared_ptr<BooleanQuery>;
} // namespace query
} // namespace milvus

View File

@ -0,0 +1,107 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "utils/Json.h"
namespace milvus {
namespace query {
enum class CompareOperator {
LT = 0,
LTE,
EQ,
GT,
GTE,
NE,
};
enum class QueryRelation {
INVALID = 0,
R1,
R2,
R3,
R4,
AND,
OR,
};
struct QueryColumn {
std::string name;
std::string column_value;
};
struct TermQuery {
std::string field_name;
std::vector<std::string> field_value;
float boost;
};
using TermQueryPtr = std::shared_ptr<TermQuery>;
struct CompareExpr {
CompareOperator compare_operator;
std::string operand;
};
struct RangeQuery {
std::string field_name;
std::vector<CompareExpr> compare_expr;
float boost;
};
using RangeQueryPtr = std::shared_ptr<RangeQuery>;
struct VectorRecord {
std::vector<float> float_data;
std::vector<uint8_t> binary_data;
};
struct VectorQuery {
std::string field_name;
milvus::json extra_params;
int64_t topk;
float boost;
VectorRecord query_vector;
};
using VectorQueryPtr = std::shared_ptr<VectorQuery>;
struct LeafQuery;
using LeafQueryPtr = std::shared_ptr<LeafQuery>;
struct BinaryQuery;
using BinaryQueryPtr = std::shared_ptr<BinaryQuery>;
struct GeneralQuery {
LeafQueryPtr leaf;
BinaryQueryPtr bin = std::make_shared<BinaryQuery>();
};
using GeneralQueryPtr = std::shared_ptr<GeneralQuery>;
struct LeafQuery {
TermQueryPtr term_query;
RangeQueryPtr range_query;
VectorQueryPtr vector_query;
float query_boost;
};
struct BinaryQuery {
GeneralQueryPtr left_query;
GeneralQueryPtr right_query;
QueryRelation relation;
float query_boost;
};
} // namespace query
} // namespace milvus

View File

@ -21,6 +21,12 @@ SearchJob::SearchJob(const std::shared_ptr<server::Context>& context, uint64_t t
: Job(JobType::SEARCH), context_(context), topk_(topk), extra_params_(extra_params), vectors_(vectors) {
}
SearchJob::SearchJob(const std::shared_ptr<server::Context>& context, milvus::query::GeneralQueryPtr general_query,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& attr_type,
const engine::VectorsData& vectors)
: Job(JobType::SEARCH), context_(context), general_query_(general_query), attr_type_(attr_type), vectors_(vectors) {
}
bool
SearchJob::AddIndexFile(const SegmentSchemaPtr& index_file) {
std::unique_lock<std::mutex> lock(mutex_);

View File

@ -26,6 +26,8 @@
#include "db/Types.h"
#include "db/meta/MetaTypes.h"
#include "query/GeneralQuery.h"
#include "server/context/Context.h"
namespace milvus {
@ -43,6 +45,10 @@ class SearchJob : public Job {
SearchJob(const std::shared_ptr<server::Context>& context, uint64_t topk, const milvus::json& extra_params,
const engine::VectorsData& vectors);
SearchJob(const std::shared_ptr<server::Context>& context, query::GeneralQueryPtr general_query,
std::unordered_map<std::string, engine::meta::hybrid::DataType>& attr_type,
const engine::VectorsData& vectorsData);
public:
bool
AddIndexFile(const SegmentSchemaPtr& index_file);
@ -99,6 +105,21 @@ class SearchJob : public Job {
return mutex_;
}
query::GeneralQueryPtr
general_query() {
return general_query_;
}
std::unordered_map<std::string, engine::meta::hybrid::DataType>&
attr_type() {
return attr_type_;
}
uint64_t&
vector_count() {
return vector_count_;
}
private:
const std::shared_ptr<server::Context> context_;
@ -113,6 +134,10 @@ class SearchJob : public Job {
ResultDistances result_distances_;
Status status_;
query::GeneralQueryPtr general_query_;
std::unordered_map<std::string, engine::meta::hybrid::DataType> attr_type_;
uint64_t vector_count_;
std::mutex mutex_;
std::condition_variable cv_;
};

View File

@ -17,6 +17,7 @@
#include <memory>
#include <string>
#include <thread>
#include <unordered_map>
#include <utility>
#include "db/Utils.h"
@ -123,6 +124,21 @@ XSearchTask::XSearchTask(const std::shared_ptr<server::Context>& context, Segmen
if (!file_->index_params_.empty()) {
json_params = milvus::json::parse(file_->index_params_);
}
// if (auto job = job_.lock()) {
// auto search_job = std::static_pointer_cast<scheduler::SearchJob>(job);
// query::GeneralQueryPtr general_query = search_job->general_query();
// if (general_query != nullptr) {
// std::unordered_map<std::string, engine::DataType> types;
// auto attr_type = search_job->attr_type();
// auto type_it = attr_type.begin();
// for (; type_it != attr_type.end(); type_it++) {
// types.insert(std::make_pair(type_it->first, (engine::DataType)(type_it->second)));
// }
// index_engine_ =
// EngineFactory::Build(file_->dimension_, file_->location_, engine_type,
// (MetricType)file_->metric_type_, types, json_params);
// }
// }
index_engine_ = EngineFactory::Build(file_->dimension_, file_->location_, engine_type,
(MetricType)file_->metric_type_, json_params);
}
@ -222,8 +238,11 @@ XSearchTask::Execute() {
}
// step 1: allocate memory
query::GeneralQueryPtr general_query = search_job->general_query();
uint64_t nq = search_job->nq();
uint64_t topk = search_job->topk();
const milvus::json& extra_params = search_job->extra_params();
const engine::VectorsData& vectors = search_job->vectors();
@ -241,6 +260,46 @@ XSearchTask::Execute() {
hybrid = true;
}
Status s;
if (general_query != nullptr) {
std::unordered_map<std::string, engine::DataType> types;
auto attr_type = search_job->attr_type();
auto type_it = attr_type.begin();
for (; type_it != attr_type.end(); type_it++) {
types.insert(std::make_pair(type_it->first, (engine::DataType)(type_it->second)));
}
faiss::ConcurrentBitsetPtr bitset;
s = index_engine_->ExecBinaryQuery(general_query, bitset, types, nq, topk, output_distance, output_ids);
if (!s.ok()) {
search_job->GetStatus() = s;
search_job->SearchDone(index_id_);
return;
}
auto spec_k = file_->row_count_ < topk ? file_->row_count_ : topk;
if (spec_k == 0) {
LOG_ENGINE_WARNING_ << "Searching in an empty file. file location = " << file_->location_;
}
{
std::unique_lock<std::mutex> lock(search_job->mutex());
if (search_job->GetResultIds().size() > spec_k) {
if (search_job->GetResultIds().front() == -1) {
// initialized results set
search_job->GetResultIds().resize(spec_k * nq);
search_job->GetResultDistances().resize(spec_k * nq);
}
}
search_job->vector_count() = nq;
XSearchTask::MergeTopkToResultSet(output_ids, output_distance, spec_k, nq, topk, ascending_reduce,
search_job->GetResultIds(), search_job->GetResultDistances());
}
search_job->SearchDone(index_id_);
index_engine_ = nullptr;
return;
}
if (!vectors.float_data_.empty()) {
s = index_engine_->Search(nq, vectors.float_data_.data(), topk, extra_params, output_distance.data(),
output_ids.data(), hybrid);

223
core/src/search/Task.cpp Normal file
View File

@ -0,0 +1,223 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#if 0
#pragma once
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "db/Utils.h"
#include "db/engine/EngineFactory.h"
#include "search/Task.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
namespace milvus {
namespace search {
Task::Task(const std::shared_ptr<server::Context>& context, SegmentSchemaPtr& file,
milvus::query::GeneralQueryPtr general_query, std::unordered_map<std::string, engine::DataType>& attr_type,
context::HybridSearchContextPtr hybrid_search_context)
: context_(context),
file_(file),
general_query_(general_query),
attr_type_(attr_type),
hybrid_search_context_(hybrid_search_context) {
if (file_) {
// distance -- value 0 means two vectors equal, ascending reduce, L2/HAMMING/JACCARD/TONIMOTO ...
// similarity -- infinity value means two vectors equal, descending reduce, IP
if (file_->metric_type_ == static_cast<int>(engine::MetricType::IP) &&
file_->engine_type_ != static_cast<int>(engine::EngineType::FAISS_PQ)) {
ascending_reduce = false;
}
engine::EngineType engine_type;
if (file->file_type_ == engine::meta::SegmentSchema::FILE_TYPE::RAW ||
file->file_type_ == engine::meta::SegmentSchema::FILE_TYPE::TO_INDEX ||
file->file_type_ == engine::meta::SegmentSchema::FILE_TYPE::BACKUP) {
engine_type = engine::utils::IsBinaryMetricType(file->metric_type_) ? engine::EngineType::FAISS_BIN_IDMAP
: engine::EngineType::FAISS_IDMAP;
} else {
engine_type = (engine::EngineType)file->engine_type_;
}
milvus::json json_params;
if (!file_->index_params_.empty()) {
json_params = milvus::json::parse(file_->index_params_);
}
index_engine_ = engine::EngineFactory::Build(file_->dimension_, file_->location_, engine_type,
(engine::MetricType)file_->metric_type_, json_params);
}
}
void
Task::Load() {
auto load_ctx = context_->Follower("XSearchTask::Load " + std::to_string(file_->id_));
Status stat = Status::OK();
std::string error_msg;
std::string type_str;
try {
stat = index_engine_->Load();
type_str = "IDSK2CPU";
} catch (std::exception& ex) {
// typical error: out of disk space or permition denied
error_msg = "Failed to load index file: " + std::string(ex.what());
stat = Status(SERVER_UNEXPECTED_ERROR, error_msg);
}
if (!stat.ok()) {
return;
}
}
void
Task::Execute() {
auto execute_ctx = context_->Follower("XSearchTask::Execute " + std::to_string(index_id_));
if (index_engine_ == nullptr) {
return;
}
TimeRecorder rc("DoSearch file id:" + std::to_string(index_id_));
std::vector<int64_t> output_ids;
std::vector<float> output_distance;
// step 1: allocate memory
try {
// step 2: search
Status s;
if (general_query_ != nullptr) {
faiss::ConcurrentBitsetPtr bitset;
uint64_t nq, topk;
s = index_engine_->ExecBinaryQuery(general_query_, bitset, attr_type_, nq, topk, output_distance,
output_ids);
if (!s.ok()) {
return;
}
auto spec_k = file_->row_count_ < topk ? file_->row_count_ : topk;
if (spec_k == 0) {
ENGINE_LOG_WARNING << "Searching in an empty file. file location = " << file_->location_;
}
{
if (result_ids_.size() > spec_k) {
if (result_ids_.front() == -1) {
result_ids_.resize(spec_k * nq);
result_distances_.resize(spec_k * nq);
}
}
Task::MergeTopkToResultSet(output_ids, output_distance, spec_k, nq, topk, ascending_reduce, result_ids_,
result_distances_);
}
index_engine_ = nullptr;
execute_ctx->GetTraceContext()->GetSpan()->Finish();
return;
}
if (!s.ok()) {
return;
}
} catch (std::exception& ex) {
ENGINE_LOG_ERROR << "SearchTask encounter exception: " << ex.what();
// search_job->IndexSearchDone(index_id_);//mark as done avoid dead lock, even search failed
}
rc.ElapseFromBegin("totally cost");
// release index in resource
index_engine_ = nullptr;
execute_ctx->GetTraceContext()->GetSpan()->Finish();
}
void
Task::MergeTopkToResultSet(const milvus::search::ResultIds& src_ids,
const milvus::search::ResultDistances& src_distances, size_t src_k, size_t nq, size_t topk,
bool ascending, milvus::search::ResultIds& tar_ids,
milvus::search::ResultDistances& tar_distances) {
if (src_ids.empty()) {
return;
}
size_t tar_k = tar_ids.size() / nq;
size_t buf_k = std::min(topk, src_k + tar_k);
ResultIds buf_ids(nq * buf_k, -1);
ResultDistances buf_distances(nq * buf_k, 0.0);
for (uint64_t i = 0; i < nq; i++) {
size_t buf_k_j = 0, src_k_j = 0, tar_k_j = 0;
size_t buf_idx, src_idx, tar_idx;
size_t buf_k_multi_i = buf_k * i;
size_t src_k_multi_i = topk * i;
size_t tar_k_multi_i = tar_k * i;
while (buf_k_j < buf_k && src_k_j < src_k && tar_k_j < tar_k) {
src_idx = src_k_multi_i + src_k_j;
tar_idx = tar_k_multi_i + tar_k_j;
buf_idx = buf_k_multi_i + buf_k_j;
if ((tar_ids[tar_idx] == -1) || // initialized value
(ascending && src_distances[src_idx] < tar_distances[tar_idx]) ||
(!ascending && src_distances[src_idx] > tar_distances[tar_idx])) {
buf_ids[buf_idx] = src_ids[src_idx];
buf_distances[buf_idx] = src_distances[src_idx];
src_k_j++;
} else {
buf_ids[buf_idx] = tar_ids[tar_idx];
buf_distances[buf_idx] = tar_distances[tar_idx];
tar_k_j++;
}
buf_k_j++;
}
if (buf_k_j < buf_k) {
if (src_k_j < src_k) {
while (buf_k_j < buf_k && src_k_j < src_k) {
buf_idx = buf_k_multi_i + buf_k_j;
src_idx = src_k_multi_i + src_k_j;
buf_ids[buf_idx] = src_ids[src_idx];
buf_distances[buf_idx] = src_distances[src_idx];
src_k_j++;
buf_k_j++;
}
} else {
while (buf_k_j < buf_k && tar_k_j < tar_k) {
buf_idx = buf_k_multi_i + buf_k_j;
tar_idx = tar_k_multi_i + tar_k_j;
buf_ids[buf_idx] = tar_ids[tar_idx];
buf_distances[buf_idx] = tar_distances[tar_idx];
tar_k_j++;
buf_k_j++;
}
}
}
}
tar_ids.swap(buf_ids);
tar_distances.swap(buf_distances);
}
} // namespace search
} // namespace milvus
#endif

93
core/src/search/Task.h Normal file
View File

@ -0,0 +1,93 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#if 0
#pragma once
#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "context/HybridSearchContext.h"
#include "db/Types.h"
#include "db/engine/ExecutionEngine.h"
#include "db/meta/MetaTypes.h"
#include "server/context/Context.h"
#include "utils/Status.h"
namespace milvus {
namespace context {
struct HybridSearchContext;
using HybridSearchContextPtr = std::shared_ptr<HybridSearchContext>;
} // namespace context
namespace search {
using SegmentSchemaPtr = engine::meta::SegmentSchemaPtr;
using Id2IndexMap = std::unordered_map<size_t, SegmentSchemaPtr>;
using ResultIds = engine::ResultIds;
using ResultDistances = engine::ResultDistances;
class Task {
public:
explicit Task(const std::shared_ptr<server::Context>& context, SegmentSchemaPtr& file,
query::GeneralQueryPtr general_query, std::unordered_map<std::string, engine::DataType>& attr_type,
context::HybridSearchContextPtr hybrid_search_context);
void
Load();
void
Execute();
public:
static void
MergeTopkToResultSet(const ResultIds& src_ids, const ResultDistances& src_distances, size_t src_k, size_t nq,
size_t topk, bool ascending, ResultIds& tar_ids, ResultDistances& tar_distances);
const std::string&
GetLocation() const;
size_t
GetIndexId() const;
public:
const std::shared_ptr<server::Context> context_;
SegmentSchemaPtr file_;
size_t index_id_ = 0;
int index_type_ = 0;
engine::ExecutionEnginePtr index_engine_ = nullptr;
// distance -- value 0 means two vectors equal, ascending reduce, L2/HAMMING/JACCARD/TONIMOTO ...
// similarity -- infinity value means two vectors equal, descending reduce, IP
bool ascending_reduce = true;
query::GeneralQueryPtr general_query_;
std::unordered_map<std::string, engine::DataType> attr_type_;
context::HybridSearchContextPtr hybrid_search_context_;
ResultIds result_ids_;
ResultDistances result_distances_;
};
using TaskPtr = std::shared_ptr<Task>;
} // namespace search
} // namespace milvus
#endif

View File

@ -0,0 +1,116 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#if 0
#pragma once
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include "search/TaskInst.h"
namespace milvus {
namespace search {
void
TaskInst::Start() {
running_ = true;
load_thread_ = std::make_shared<std::thread>(&TaskInst::StartLoadTask, this);
exec_thread_ = std::make_shared<std::thread>(&TaskInst::StartExecuteTask, this);
}
void
TaskInst::Stop() {
running_ = false;
StopExecuteTask();
StopLoadTask();
}
std::queue<TaskPtr>&
TaskInst::load_queue() {
return load_queue_;
}
std::queue<TaskPtr>&
TaskInst::exec_queue() {
return exec_queue_;
}
std::condition_variable&
TaskInst::load_cv() {
return load_cv_;
}
std::condition_variable&
TaskInst::exec_cv() {
return exec_cv_;
}
void
TaskInst::StartLoadTask() {
while (running_) {
std::unique_lock<std::mutex> lock(load_mutex_);
load_cv_.wait(lock, [this] { return !load_queue_.empty(); });
while (!load_queue_.empty()) {
auto task = load_queue_.front();
task->Load();
load_queue_.pop();
exec_queue_.push(task);
exec_cv_.notify_one();
}
}
}
void
TaskInst::StartExecuteTask() {
while (running_) {
std::unique_lock<std::mutex> lock(exec_mutex_);
exec_cv_.wait(lock, [this] { return !exec_queue_.empty(); });
while (!exec_queue_.empty()) {
auto task = exec_queue_.front();
task->Execute();
exec_queue_.pop();
}
}
}
void
TaskInst::StopLoadTask() {
{
std::lock_guard<std::mutex> lock(load_mutex_);
load_queue_.push(nullptr);
load_cv_.notify_one();
if (load_thread_->joinable()) {
load_thread_->join();
}
load_thread_ = nullptr;
}
}
void
TaskInst::StopExecuteTask() {
{
std::lock_guard<std::mutex> lock(exec_mutex_);
exec_queue_.push(nullptr);
exec_cv_.notify_one();
if (exec_thread_->joinable()) {
exec_thread_->join();
}
exec_thread_ = nullptr;
}
}
} // namespace search
} // namespace milvus
#endif

View File

@ -0,0 +1,82 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#if 0
#pragma once
#include <condition_variable>
#include <iostream>
#include <memory>
#include <queue>
#include <string>
#include <thread>
#include <vector>
#include "Task.h"
namespace milvus {
namespace search {
class TaskInst {
public:
static TaskInst&
GetInstance() {
static TaskInst instance;
return instance;
}
void
Start();
void
Stop();
std::queue<TaskPtr>&
load_queue();
std::queue<TaskPtr>&
exec_queue();
std::condition_variable&
load_cv();
std::condition_variable&
exec_cv();
private:
TaskInst() = default;
~TaskInst() = default;
void
StartLoadTask();
void
StartExecuteTask();
void
StopLoadTask();
void
StopExecuteTask();
private:
bool running_;
std::shared_ptr<std::thread> load_thread_;
std::shared_ptr<std::thread> exec_thread_;
std::queue<TaskPtr> load_queue_;
std::queue<TaskPtr> exec_queue_;
std::condition_variable load_cv_;
std::condition_variable exec_cv_;
std::mutex exec_mutex_;
std::mutex load_mutex_;
};
} // namespace search
} // namespace milvus
#endif

168
core/src/segment/Attr.cpp Normal file
View File

@ -0,0 +1,168 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <algorithm>
#include <chrono>
#include <cstring>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "Vectors.h"
#include "segment/Attr.h"
#include "utils/Log.h"
namespace milvus {
namespace segment {
Attr::Attr(const std::vector<uint8_t>& data, size_t nbytes, const std::vector<int64_t> uids, const std::string& name)
: data_(std::move(data)), nbytes_(nbytes), uids_(std::move(uids)), name_(name) {
}
void
Attr::AddAttr(const std::vector<uint8_t>& data, size_t nbytes) {
data_.reserve(data_.size() + data.size());
data_.insert(data_.end(), std::make_move_iterator(data.begin()), std::make_move_iterator(data.end()));
nbytes_ += nbytes;
}
void
Attr::AddUids(const std::vector<int64_t>& uids) {
uids_.reserve(uids_.size() + uids.size());
uids_.insert(uids_.end(), std::make_move_iterator(uids.begin()), std::make_move_iterator(uids.end()));
}
void
Attr::SetName(const std::string& name) {
name_ = name;
}
const std::vector<uint8_t>&
Attr::GetData() const {
return data_;
}
const std::string&
Attr::GetName() const {
return name_;
}
const std::string&
Attr::GetCollectionId() {
return collection_id_;
}
const size_t&
Attr::GetNbytes() const {
return nbytes_;
}
const std::vector<int64_t>&
Attr::GetUids() const {
return uids_;
}
size_t
Attr::GetCount() const {
return uids_.size();
}
size_t
Attr::GetCodeLength() const {
return uids_.size() == 0 ? 0 : nbytes_ / uids_.size();
}
void
Attr::Erase(int32_t offset) {
auto code_length = GetCodeLength();
if (code_length != 0) {
auto step = offset * code_length;
data_.erase(data_.begin() + step, data_.begin() + step + code_length);
uids_.erase(uids_.begin() + offset, uids_.begin() + offset + 1);
}
}
void
Attr::Erase(std::vector<int32_t>& offsets) {
if (offsets.empty()) {
return;
}
// Sort and remove duplicates
auto start = std::chrono::high_resolution_clock::now();
std::sort(offsets.begin(), offsets.end());
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;
LOG_ENGINE_DEBUG_ << "Sorting " << offsets.size() << " offsets to delete took " << diff.count() << " s";
start = std::chrono::high_resolution_clock::now();
offsets.erase(std::unique(offsets.begin(), offsets.end()), offsets.end());
end = std::chrono::high_resolution_clock::now();
diff = end - start;
LOG_ENGINE_DEBUG_ << "Deduplicating " << offsets.size() << " offsets to delete took " << diff.count() << " s";
LOG_ENGINE_DEBUG_ << "Attributes begin erasing...";
size_t new_size = uids_.size() - offsets.size();
std::vector<doc_id_t> new_uids(new_size);
auto code_length = GetCodeLength();
std::vector<uint8_t> new_data(new_size * code_length);
auto count = 0;
auto skip = offsets.cbegin();
auto loop_size = uids_.size();
for (size_t i = 0; i < loop_size;) {
while (skip != offsets.cend() && i == *skip) {
++i;
++skip;
}
if (i == loop_size) {
break;
}
new_uids[count] = uids_[i];
for (size_t j = 0; j < code_length; ++j) {
new_data[count * code_length + j] = data_[i * code_length + j];
}
++count;
++i;
}
data_.clear();
uids_.clear();
data_.swap(new_data);
uids_.swap(new_uids);
end = std::chrono::high_resolution_clock::now();
diff = end - start;
LOG_ENGINE_DEBUG_ << "Erasing " << offsets.size() << " vectors out of " << loop_size << " vectors took "
<< diff.count() << " s";
}
} // namespace segment
} // namespace milvus

View File

@ -18,13 +18,53 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
namespace milvus {
namespace segment {
class Attr {
public:
Attr(void* data, size_t nbytes);
Attr(const std::vector<uint8_t>& data, size_t nbytes, const std::vector<int64_t> uids, const std::string& name);
Attr();
void
AddAttr(const std::vector<uint8_t>& data, size_t nbytes);
void
AddUids(const std::vector<int64_t>& uids);
void
SetName(const std::string& name);
const std::vector<uint8_t>&
GetData() const;
const std::string&
GetName() const;
const std::string&
GetCollectionId();
const size_t&
GetNbytes() const;
const std::vector<int64_t>&
GetUids() const;
size_t
GetCount() const;
size_t
GetCodeLength() const;
void
Erase(int32_t offset);
void
Erase(std::vector<int32_t>& offsets);
// No copy and move
Attr(const Attr&) = delete;
@ -36,8 +76,11 @@ class Attr {
operator=(Attr&&) = delete;
private:
void* data_;
std::vector<uint8_t> data_;
size_t nbytes_;
std::vector<int64_t> uids_;
std::string name_;
std::string collection_id_;
};
using AttrPtr = std::shared_ptr<Attr>;

View File

@ -17,6 +17,7 @@
#pragma once
#include <memory>
#include <string>
#include <unordered_map>
@ -26,8 +27,12 @@ namespace milvus {
namespace segment {
struct Attrs {
// Attrs() = default;
std::unordered_map<std::string, AttrPtr> attrs;
};
using AttrsPtr = std::shared_ptr<Attrs>;
} // namespace segment
} // namespace milvus

View File

@ -50,6 +50,7 @@ SegmentReader::Load() {
try {
fs_ptr_->operation_ptr_->CreateDirectory();
default_codec.GetVectorsFormat()->read(fs_ptr_, segment_ptr_->vectors_ptr_);
default_codec.GetAttrsFormat()->read(fs_ptr_, segment_ptr_->attrs_ptr_);
// default_codec.GetVectorIndexFormat()->read(fs_ptr_, segment_ptr_->vector_index_ptr_);
default_codec.GetDeletedDocsFormat()->read(fs_ptr_, segment_ptr_->deleted_docs_ptr_);
} catch (std::exception& e) {

View File

@ -19,6 +19,7 @@
#include <algorithm>
#include <memory>
#include <utility>
#include "SegmentReader.h"
#include "Vectors.h"
@ -50,6 +51,26 @@ SegmentWriter::AddVectors(const std::string& name, const std::vector<uint8_t>& d
return Status::OK();
}
Status
SegmentWriter::AddAttrs(const std::string& name, const std::unordered_map<std::string, uint64_t>& attr_nbytes,
const std::unordered_map<std::string, std::vector<uint8_t>>& attr_data,
const std::vector<doc_id_t>& uids) {
auto attr_data_it = attr_data.begin();
auto attrs = segment_ptr_->attrs_ptr_->attrs;
for (; attr_data_it != attr_data.end(); ++attr_data_it) {
if (attrs.find(attr_data_it->first) != attrs.end()) {
segment_ptr_->attrs_ptr_->attrs.at(attr_data_it->first)
->AddAttr(attr_data_it->second, attr_nbytes.at(attr_data_it->first));
segment_ptr_->attrs_ptr_->attrs.at(attr_data_it->first)->AddUids(uids);
} else {
AttrPtr attr = std::make_shared<Attr>(attr_data_it->second, attr_nbytes.at(attr_data_it->first), uids,
attr_data_it->first);
segment_ptr_->attrs_ptr_->attrs.insert(std::make_pair(attr_data_it->first, attr));
}
}
return Status::OK();
}
Status
SegmentWriter::SetVectorIndex(const milvus::knowhere::VecIndexPtr& index) {
segment_ptr_->vector_index_ptr_->SetVectorIndex(index);
@ -74,6 +95,11 @@ SegmentWriter::Serialize() {
return status;
}
status = WriteAttrs();
if (!status.ok()) {
return status;
}
recorder.RecordSection("Writing vectors and uids done");
// Write an empty deleted doc
@ -98,6 +124,20 @@ SegmentWriter::WriteVectors() {
return Status::OK();
}
Status
SegmentWriter::WriteAttrs() {
codec::DefaultCodec default_codec;
try {
fs_ptr_->operation_ptr_->CreateDirectory();
default_codec.GetAttrsFormat()->write(fs_ptr_, segment_ptr_->attrs_ptr_);
} catch (std::exception& e) {
std::string err_msg = "Failed to write vectors: " + std::string(e.what());
LOG_ENGINE_ERROR_ << err_msg;
return Status(SERVER_WRITE_ERROR, err_msg);
}
return Status::OK();
}
Status
SegmentWriter::WriteVectorIndex(const std::string& location) {
codec::DefaultCodec default_codec;
@ -238,6 +278,22 @@ SegmentWriter::Merge(const std::string& dir_to_merge, const std::string& name) {
auto rows = segment_to_merge->vectors_ptr_->GetCount();
recorder.RecordSection("Adding " + std::to_string(rows) + " vectors and uids");
std::unordered_map<std::string, uint64_t> attr_nbytes;
std::unordered_map<std::string, std::vector<uint8_t>> attr_data;
auto attr_it = segment_to_merge->attrs_ptr_->attrs.begin();
for (; attr_it != segment_to_merge->attrs_ptr_->attrs.end(); attr_it++) {
attr_nbytes.insert(std::make_pair(attr_it->first, attr_it->second->GetNbytes()));
attr_data.insert(std::make_pair(attr_it->first, attr_it->second->GetData()));
if (segment_to_merge->deleted_docs_ptr_ != nullptr) {
auto offsets_to_delete = segment_to_merge->deleted_docs_ptr_->GetDeletedDocs();
// Erase from field data
attr_it->second->Erase(offsets_to_delete);
}
}
AddAttrs(name, attr_nbytes, attr_data, segment_to_merge->vectors_ptr_->GetUids());
LOG_ENGINE_DEBUG_ << "Merging completed from " << dir_to_merge << " to " << fs_ptr_->operation_ptr_->GetDirectory();
return Status::OK();

View File

@ -19,6 +19,7 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "segment/Types.h"
@ -35,6 +36,10 @@ class SegmentWriter {
Status
AddVectors(const std::string& name, const std::vector<uint8_t>& data, const std::vector<doc_id_t>& uids);
Status
AddAttrs(const std::string& name, const std::unordered_map<std::string, uint64_t>& attr_nbytes,
const std::unordered_map<std::string, std::vector<uint8_t>>& attr_data, const std::vector<doc_id_t>& uids);
Status
SetVectorIndex(const knowhere::VecIndexPtr& index);
@ -69,6 +74,9 @@ class SegmentWriter {
Status
WriteVectors();
Status
WriteAttrs();
Status
WriteBloomFilter();

View File

@ -19,6 +19,7 @@
#include <memory>
#include "segment/Attrs.h"
#include "segment/DeletedDocs.h"
#include "segment/IdBloomFilter.h"
#include "segment/VectorIndex.h"
@ -31,6 +32,7 @@ typedef int64_t doc_id_t;
struct Segment {
VectorsPtr vectors_ptr_ = std::make_shared<Vectors>();
AttrsPtr attrs_ptr_ = std::make_shared<Attrs>();
VectorIndexPtr vector_index_ptr_ = std::make_shared<VectorIndex>();
DeletedDocsPtr deleted_docs_ptr_ = nullptr;
IdBloomFilterPtr id_bloom_filter_ptr_ = nullptr;

View File

@ -30,6 +30,8 @@
#include "utils/SignalUtil.h"
#include "utils/TimeRecorder.h"
#include "search/TaskInst.h"
namespace milvus {
namespace server {
@ -283,6 +285,8 @@ Server::StartService() {
// goto FAIL;
// }
// search::TaskInst::GetInstance().Start();
return Status::OK();
FAIL:
std::cerr << "Milvus initializes fail: " << stat.message() << std::endl;
@ -291,6 +295,7 @@ FAIL:
void
Server::StopService() {
// search::TaskInst::GetInstance().Stop();
// storage::S3ClientWrapper::GetInstance().StopService();
web::WebServer::GetInstance().Stop();
grpc::GrpcServer::GetInstance().Stop();

View File

@ -39,6 +39,10 @@
#include "server/delivery/request/ShowCollectionsRequest.h"
#include "server/delivery/request/ShowPartitionsRequest.h"
#include "server/delivery/hybrid_request/CreateHybridCollectionRequest.h"
#include "server/delivery/hybrid_request/HybridSearchRequest.h"
#include "server/delivery/hybrid_request/InsertEntityRequest.h"
namespace milvus {
namespace server {
@ -248,5 +252,48 @@ RequestHandler::Compact(const std::shared_ptr<Context>& context, const std::stri
return request_ptr->status();
}
/*******************************************New Interface*********************************************/
Status
RequestHandler::CreateHybridCollection(const std::shared_ptr<Context>& context, const std::string& collection_name,
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>>& field_types,
std::vector<std::pair<std::string, uint64_t>>& vector_dimensions,
std::vector<std::pair<std::string, std::string>>& field_extra_params) {
BaseRequestPtr request_ptr = CreateHybridCollectionRequest::Create(context, collection_name, field_types,
vector_dimensions, field_extra_params);
RequestScheduler::ExecRequest(request_ptr);
return request_ptr->status();
}
Status
RequestHandler::HasHybridCollection(const std::shared_ptr<Context>& context, std::string& collection_name,
bool& has_collection) {
}
Status
RequestHandler::InsertEntity(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas) {
BaseRequestPtr request_ptr =
InsertEntityRequest::Create(context, collection_name, partition_tag, field_values, vector_datas);
RequestScheduler::ExecRequest(request_ptr);
return request_ptr->status();
}
Status
RequestHandler::HybridSearch(const std::shared_ptr<Context>& context,
context::HybridSearchContextPtr hybrid_search_context, const std::string& collection_name,
std::vector<std::string>& partition_list, milvus::query::GeneralQueryPtr& general_query,
TopKQueryResult& result) {
BaseRequestPtr request_ptr = HybridSearchRequest::Create(context, hybrid_search_context, collection_name,
partition_list, general_query, result);
RequestScheduler::ExecRequest(request_ptr);
return request_ptr->status();
}
} // namespace server
} // namespace milvus

View File

@ -13,9 +13,12 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "context/HybridSearchContext.h"
#include "query/BooleanQuery.h"
#include "server/delivery/request/BaseRequest.h"
#include "utils/Status.h"
@ -109,6 +112,31 @@ class RequestHandler {
Status
Compact(const std::shared_ptr<Context>& context, const std::string& collection_name);
/*******************************************New Interface*********************************************/
Status
CreateHybridCollection(const std::shared_ptr<Context>& context, const std::string& collection_name,
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>>& field_types,
std::vector<std::pair<std::string, uint64_t>>& vector_dimensions,
std::vector<std::pair<std::string, std::string>>& field_extra_params);
Status
HasHybridCollection(const std::shared_ptr<Context>& context, std::string& collection_name, bool& has_collection);
Status
DropHybridCollection(const std::shared_ptr<Context>& context, std::string& collection_name);
Status
InsertEntity(const std::shared_ptr<Context>& context, const std::string& collection_name,
const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas);
Status
HybridSearch(const std::shared_ptr<Context>& context, context::HybridSearchContextPtr hybrid_search_context,
const std::string& collection_name, std::vector<std::string>& partition_list,
query::GeneralQueryPtr& boolean_query, TopKQueryResult& result);
};
} // namespace server

View File

@ -0,0 +1,102 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#include "server/delivery/hybrid_request/CreateHybridCollectionRequest.h"
#include "db/Utils.h"
#include "server/DBWrapper.h"
#include "server/delivery/request/BaseRequest.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
#include "utils/ValidationUtil.h"
#include <fiu-local.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
namespace milvus {
namespace server {
CreateHybridCollectionRequest::CreateHybridCollectionRequest(
const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>>& field_types,
std::vector<std::pair<std::string, uint64_t>>& vector_dimensions,
std::vector<std::pair<std::string, std::string>>& field_params)
: BaseRequest(context, BaseRequest::kCreateHybridCollection),
collection_name_(collection_name),
field_types_(field_types),
vector_dimensions_(vector_dimensions),
field_params_(field_params) {
}
BaseRequestPtr
CreateHybridCollectionRequest::Create(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name,
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>>& field_types,
std::vector<std::pair<std::string, uint64_t>>& vector_dimensions,
std::vector<std::pair<std::string, std::string>>& field_params) {
return std::shared_ptr<BaseRequest>(
new CreateHybridCollectionRequest(context, collection_name, field_types, vector_dimensions, field_params));
}
Status
CreateHybridCollectionRequest::OnExecute() {
std::string hdr = "CreateCollectionRequest(collection=" + collection_name_ + ")";
TimeRecorderAuto rc(hdr);
try {
// step 1: check arguments
auto status = ValidationUtil::ValidateCollectionName(collection_name_);
if (!status.ok()) {
return status;
}
rc.RecordSection("check validation");
// step 2: construct collection schema and vector schema
engine::meta::CollectionSchema table_info;
engine::meta::hybrid::FieldsSchema fields_schema;
auto size = field_types_.size();
table_info.collection_id_ = collection_name_;
fields_schema.fields_schema_.resize(size + 1);
for (uint64_t i = 0; i < size; ++i) {
fields_schema.fields_schema_[i].collection_id_ = collection_name_;
fields_schema.fields_schema_[i].field_name_ = field_types_[i].first;
fields_schema.fields_schema_[i].field_type_ = (int32_t)field_types_[i].second;
fields_schema.fields_schema_[i].field_params_ = field_params_[i].second;
}
fields_schema.fields_schema_[size].collection_id_ = collection_name_;
fields_schema.fields_schema_[size].field_name_ = vector_dimensions_[0].first;
fields_schema.fields_schema_[size].field_type_ = (int32_t)engine::meta::hybrid::DataType::VECTOR;
table_info.dimension_ = vector_dimensions_[0].second;
// TODO(yukun): check dimension, metric_type, and assign engine_type
// step 3: create collection
status = DBWrapper::DB()->CreateHybridCollection(table_info, fields_schema);
if (!status.ok()) {
// collection could exist
if (status.code() == DB_ALREADY_EXIST) {
return Status(SERVER_INVALID_COLLECTION_NAME, status.message());
}
return status;
}
} catch (std::exception& ex) {
return Status(SERVER_UNEXPECTED_ERROR, ex.what());
}
return Status::OK();
}
} // namespace server
} // namespace milvus

View File

@ -0,0 +1,50 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "server/delivery/request/BaseRequest.h"
namespace milvus {
namespace server {
class CreateHybridCollectionRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>>& field_types,
std::vector<std::pair<std::string, uint64_t>>& vector_dimensions,
std::vector<std::pair<std::string, std::string>>& field_params);
protected:
CreateHybridCollectionRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name,
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>>& field_types,
std::vector<std::pair<std::string, uint64_t>>& vector_dimensions,
std::vector<std::pair<std::string, std::string>>& field_arams);
Status
OnExecute() override;
private:
const std::string collection_name_;
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>>& field_types_;
std::vector<std::pair<std::string, uint64_t>> vector_dimensions_;
std::vector<std::pair<std::string, std::string>>& field_params_;
};
} // namespace server
} // namespace milvus

View File

@ -0,0 +1,134 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#include "server/delivery/hybrid_request/HybridSearchRequest.h"
#include "db/Utils.h"
#include "server/DBWrapper.h"
#include "utils/CommonUtil.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
#include "utils/ValidationUtil.h"
#include <fiu-local.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#ifdef MILVUS_ENABLE_PROFILING
#include <gperftools/profiler.h>
#endif
namespace milvus {
namespace server {
HybridSearchRequest::HybridSearchRequest(const std::shared_ptr<milvus::server::Context>& context,
context::HybridSearchContextPtr& hybrid_search_context,
const std::string& collection_name, std::vector<std::string>& partition_list,
milvus::query::GeneralQueryPtr& general_query, TopKQueryResult& result)
: BaseRequest(context, BaseRequest::kHybridSearch),
hybrid_search_contxt_(hybrid_search_context),
collection_name_(collection_name),
partition_list_(partition_list),
general_query_(general_query),
result_(result) {
}
BaseRequestPtr
HybridSearchRequest::Create(const std::shared_ptr<milvus::server::Context>& context,
context::HybridSearchContextPtr& hybrid_search_context, const std::string& collection_name,
std::vector<std::string>& partition_list, milvus::query::GeneralQueryPtr& general_query,
TopKQueryResult& result) {
return std::shared_ptr<BaseRequest>(new HybridSearchRequest(context, hybrid_search_context, collection_name,
partition_list, general_query, result));
}
Status
HybridSearchRequest::OnExecute() {
try {
fiu_do_on("SearchRequest.OnExecute.throw_std_exception", throw std::exception());
std::string hdr = "SearchRequest(table=" + collection_name_;
TimeRecorder rc(hdr);
// step 1: check table name
auto status = ValidationUtil::ValidateCollectionName(collection_name_);
if (!status.ok()) {
return status;
}
// step 2: check table existence
// only process root table, ignore partition table
engine::meta::CollectionSchema collection_schema;
engine::meta::hybrid::FieldsSchema fields_schema;
collection_schema.collection_id_ = collection_name_;
status = DBWrapper::DB()->DescribeHybridCollection(collection_schema, fields_schema);
fiu_do_on("SearchRequest.OnExecute.describe_table_fail", status = Status(milvus::SERVER_UNEXPECTED_ERROR, ""));
if (!status.ok()) {
if (status.code() == DB_NOT_FOUND) {
return Status(SERVER_COLLECTION_NOT_EXIST, CollectionNotExistMsg(collection_name_));
} else {
return status;
}
} else {
if (!collection_schema.owner_collection_.empty()) {
return Status(SERVER_INVALID_COLLECTION_NAME, CollectionNotExistMsg(collection_name_));
}
}
std::unordered_map<std::string, engine::meta::hybrid::DataType> attr_type;
for (uint64_t i = 0; i < fields_schema.fields_schema_.size(); ++i) {
attr_type.insert(
std::make_pair(fields_schema.fields_schema_[i].field_name_,
(engine::meta::hybrid::DataType)fields_schema.fields_schema_[i].field_type_));
}
engine::ResultIds result_ids;
engine::ResultDistances result_distances;
uint64_t nq;
status = DBWrapper::DB()->HybridQuery(context_, collection_name_, partition_list_, hybrid_search_contxt_,
general_query_, attr_type, nq, result_ids, result_distances);
#ifdef MILVUS_ENABLE_PROFILING
ProfilerStop();
#endif
fiu_do_on("SearchRequest.OnExecute.query_fail", status = Status(milvus::SERVER_UNEXPECTED_ERROR, ""));
if (!status.ok()) {
return status;
}
fiu_do_on("SearchRequest.OnExecute.empty_result_ids", result_ids.clear());
if (result_ids.empty()) {
return Status::OK(); // empty table
}
auto post_query_ctx = context_->Child("Constructing result");
// step 7: construct result array
result_.row_num_ = nq;
result_.distance_list_ = result_distances;
result_.id_list_ = result_ids;
post_query_ctx->GetTraceContext()->GetSpan()->Finish();
// step 8: print time cost percent
rc.RecordSection("construct result and send");
rc.ElapseFromBegin("totally cost");
} catch (std::exception& ex) {
return Status(SERVER_UNEXPECTED_ERROR, ex.what());
}
return Status::OK();
}
} // namespace server
} // namespace milvus

View File

@ -0,0 +1,50 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include "server/delivery/request/BaseRequest.h"
#include <src/context/HybridSearchContext.h>
#include <memory>
#include <string>
#include <vector>
namespace milvus {
namespace server {
class HybridSearchRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context,
context::HybridSearchContextPtr& hybrid_search_context, const std::string& collection_name,
std::vector<std::string>& partition_list, milvus::query::GeneralQueryPtr& general_query,
TopKQueryResult& result);
protected:
HybridSearchRequest(const std::shared_ptr<milvus::server::Context>& context,
context::HybridSearchContextPtr& hybrid_search_context, const std::string& collection_name,
std::vector<std::string>& partition_list, milvus::query::GeneralQueryPtr& general_query,
TopKQueryResult& result);
Status
OnExecute() override;
private:
context::HybridSearchContextPtr hybrid_search_contxt_;
const std::string collection_name_;
std::vector<std::string>& partition_list_;
milvus::query::GeneralQueryPtr& general_query_;
TopKQueryResult& result_;
};
} // namespace server
} // namespace milvus

View File

@ -0,0 +1,205 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#include "server/delivery/hybrid_request/InsertEntityRequest.h"
#include "db/Utils.h"
#include "server/DBWrapper.h"
#include "utils/CommonUtil.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
#include "utils/ValidationUtil.h"
#include <fiu-local.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#ifdef MILVUS_ENABLE_PROFILING
#include <gperftools/profiler.h>
#endif
namespace milvus {
namespace server {
InsertEntityRequest::InsertEntityRequest(const std::shared_ptr<milvus::server::Context>& context,
const std::string& collection_name, const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas)
: BaseRequest(context, BaseRequest::kInsertEntity),
collection_name_(collection_name),
partition_tag_(partition_tag),
field_values_(field_values),
vector_datas_(vector_datas) {
}
BaseRequestPtr
InsertEntityRequest::Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas) {
return std::shared_ptr<BaseRequest>(
new InsertEntityRequest(context, collection_name, partition_tag, field_values, vector_datas));
}
Status
InsertEntityRequest::OnExecute() {
try {
fiu_do_on("InsertEntityRequest.OnExecute.throw_std_exception", throw std::exception());
std::string hdr = "InsertEntityRequest(table=" + collection_name_ + ", n=" + field_values_.begin()->first +
", partition_tag=" + partition_tag_ + ")";
TimeRecorder rc(hdr);
// step 1: check arguments
auto status = ValidationUtil::ValidateCollectionName(collection_name_);
if (!status.ok()) {
return status;
}
auto vector_datas_it = vector_datas_.begin();
if (vector_datas_it->second.float_data_.empty() && vector_datas_it->second.binary_data_.empty()) {
return Status(SERVER_INVALID_ROWRECORD_ARRAY,
"The vector array is emp ty. Make sure you have entered vector records.");
}
// step 2: check table existence
// only process root table, ignore partition table
engine::meta::CollectionSchema collection_schema;
engine::meta::hybrid::FieldsSchema fields_schema;
collection_schema.collection_id_ = collection_name_;
status = DBWrapper::DB()->DescribeHybridCollection(collection_schema, fields_schema);
if (!status.ok()) {
if (status.code() == DB_NOT_FOUND) {
return Status(SERVER_COLLECTION_NOT_EXIST, CollectionNotExistMsg(collection_name_));
} else {
return status;
}
} else {
if (!collection_schema.owner_collection_.empty()) {
return Status(SERVER_INVALID_COLLECTION_NAME, CollectionNotExistMsg(collection_name_));
}
}
std::unordered_map<std::string, engine::meta::hybrid::DataType> field_types;
auto size = fields_schema.fields_schema_.size();
for (uint64_t i = 0; i < size; ++i) {
if (fields_schema.fields_schema_[i].field_type_ == (int32_t)engine::meta::hybrid::DataType::VECTOR) {
continue;
}
field_types.insert(
std::make_pair(fields_schema.fields_schema_[i].field_name_,
(engine::meta::hybrid::DataType)fields_schema.fields_schema_[i].field_type_));
}
// step 3: check table flag
// all user provide id, or all internal id
bool user_provide_ids = !vector_datas_it->second.id_array_.empty();
fiu_do_on("InsertEntityRequest.OnExecute.illegal_vector_id", user_provide_ids = false;
collection_schema.flag_ = engine::meta::FLAG_MASK_HAS_USERID);
// user already provided id before, all insert action require user id
if ((collection_schema.flag_ & engine::meta::FLAG_MASK_HAS_USERID) != 0 && !user_provide_ids) {
return Status(SERVER_ILLEGAL_VECTOR_ID,
"Collection vector IDs are user-defined. Please provide IDs for all vectors of this table.");
}
fiu_do_on("InsertRequest.OnExecute.illegal_vector_id2", user_provide_ids = true;
collection_schema.flag_ = engine::meta::FLAG_MASK_NO_USERID);
// user didn't provided id before, no need to provide user id
if ((collection_schema.flag_ & engine::meta::FLAG_MASK_NO_USERID) != 0 && user_provide_ids) {
return Status(
SERVER_ILLEGAL_VECTOR_ID,
"Table vector IDs are auto-generated. All vectors of this table must use auto-generated IDs.");
}
rc.RecordSection("check validation");
#ifdef MILVUS_ENABLE_PROFILING
std::string fname = "/tmp/insert_" + CommonUtil::GetCurrentTimeStr() + ".profiling";
ProfilerStart(fname.c_str());
#endif
// step 4: some metric type doesn't support float vectors
// TODO(yukun): check dimension and metric_type
// for (uint64_t i = 0; i <entities_.vector_data_.size(); ++i) {
// if (!entities_.vector_data_[i].float_data_.empty()) { // insert float vectors
// if (engine::utils::IsBinaryMetricType(vector_fields.vector_fields_[i].metric_type_)) {
// return Status(SERVER_INVALID_ROWRECORD_ARRAY, "Table metric type doesn't support float
// vectors.");
// }
//
// // check prepared float data
// fiu_do_on("InsertRequest.OnExecute.invalid_dim", table_schema.dimension_ = -1);
// if (entities_.vector_data_[i].float_data_.size() / entities_.vector_data_[i].vector_count_ !=
// vector_fields.vector_fields_[i].dimension_) {
// return Status(SERVER_INVALID_VECTOR_DIMENSION,
// "The vector dimension must be equal to the table dimension.");
// }
// } else if (!entities_.vector_data_[i].binary_data_.empty()) { // insert binary vectors
// if (!engine::utils::IsBinaryMetricType(vector_fields.vector_fields_[i].metric_type_)) {
// return Status(SERVER_INVALID_ROWRECORD_ARRAY, "Table metric type doesn't support binary
// vectors.");
// }
//
// // check prepared binary data
// if (entities_.vector_data_[i].binary_data_.size() * 8 /
// entities_.vector_data_[i].vector_count_ != vector_fields.vector_fields_[i].dimension_) {
// return Status(SERVER_INVALID_VECTOR_DIMENSION,
// "The vector dimension must be equal to the table dimension.");
// }
// }
// }
// step 5: insert entities
auto vec_count = static_cast<uint64_t>(vector_datas_it->second.vector_count_);
engine::Entity entity;
entity.entity_count_ = vector_datas_it->second.vector_count_;
entity.attr_data_ = field_values_;
entity.vector_data_.insert(std::make_pair(vector_datas_it->first, vector_datas_it->second));
rc.RecordSection("prepare vectors data");
status = DBWrapper::DB()->InsertEntities(collection_name_, partition_tag_, entity, field_types);
fiu_do_on("InsertRequest.OnExecute.insert_fail", status = Status(milvus::SERVER_UNEXPECTED_ERROR, ""));
if (!status.ok()) {
return status;
}
vector_datas_it->second.id_array_ = entity.id_array_;
// auto ids_size = vectors_data_.id_array_.size();
// fiu_do_on("InsertRequest.OnExecute.invalid_ids_size", ids_size = vec_count - 1);
// if (ids_size != vec_count) {
// std::string msg =
// "Add " + std::to_string(vec_count) + " vectors but only return " + std::to_string(ids_size) +
// " id";
// return Status(SERVER_ILLEGAL_VECTOR_ID, msg);
// }
// step 6: update table flag
user_provide_ids ? collection_schema.flag_ |= engine::meta::FLAG_MASK_HAS_USERID
: collection_schema.flag_ |= engine::meta::FLAG_MASK_NO_USERID;
status = DBWrapper::DB()->UpdateCollectionFlag(collection_name_, collection_schema.flag_);
#ifdef MILVUS_ENABLE_PROFILING
ProfilerStop();
#endif
rc.RecordSection("add vectors to engine");
rc.ElapseFromBegin("total cost");
} catch (std::exception& ex) {
return Status(SERVER_UNEXPECTED_ERROR, ex.what());
}
return Status::OK();
}
} // namespace server
} // namespace milvus

View File

@ -0,0 +1,48 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include "server/delivery/request/BaseRequest.h"
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
namespace milvus {
namespace server {
class InsertEntityRequest : public BaseRequest {
public:
static BaseRequestPtr
Create(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& partition_tag, std::unordered_map<std::string, std::vector<std::string>>& field_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas);
protected:
InsertEntityRequest(const std::shared_ptr<milvus::server::Context>& context, const std::string& collection_name,
const std::string& partition_tag,
std::unordered_map<std::string, std::vector<std::string>>& field_values,
std::unordered_map<std::string, engine::VectorsData>& vector_datas);
Status
OnExecute() override;
private:
const std::string collection_name_;
const std::string partition_tag_;
std::unordered_map<std::string, std::vector<std::string>> field_values_;
std::unordered_map<std::string, engine::VectorsData>& vector_datas_;
};
} // namespace server
} // namespace milvus

View File

@ -37,6 +37,7 @@ RequestGroup(BaseRequest::RequestType type) {
{BaseRequest::kDeleteByID, DDL_DML_REQUEST_GROUP},
{BaseRequest::kGetVectorByID, INFO_REQUEST_GROUP},
{BaseRequest::kGetVectorIDs, INFO_REQUEST_GROUP},
{BaseRequest::kInsertEntity, DDL_DML_REQUEST_GROUP},
// collection operations
{BaseRequest::kShowCollections, INFO_REQUEST_GROUP},
@ -47,6 +48,7 @@ RequestGroup(BaseRequest::RequestType type) {
{BaseRequest::kShowCollectionInfo, INFO_REQUEST_GROUP},
{BaseRequest::kDropCollection, DDL_DML_REQUEST_GROUP},
{BaseRequest::kPreloadCollection, DQL_REQUEST_GROUP},
{BaseRequest::kCreateHybridCollection, DDL_DML_REQUEST_GROUP},
// partition operations
{BaseRequest::kCreatePartition, DDL_DML_REQUEST_GROUP},
@ -62,6 +64,7 @@ RequestGroup(BaseRequest::RequestType type) {
{BaseRequest::kSearchByID, DQL_REQUEST_GROUP},
{BaseRequest::kSearch, DQL_REQUEST_GROUP},
{BaseRequest::kSearchCombine, DQL_REQUEST_GROUP},
{BaseRequest::kHybridSearch, DQL_REQUEST_GROUP},
};
auto iter = s_map_type_group.find(type);

View File

@ -16,6 +16,7 @@
#include "grpc/gen-milvus/milvus.grpc.pb.h"
#include "grpc/gen-status/status.grpc.pb.h"
#include "grpc/gen-status/status.pb.h"
#include "query/GeneralQuery.h"
#include "server/context/Context.h"
#include "utils/Json.h"
#include "utils/Status.h"
@ -68,6 +69,13 @@ struct TopKQueryResult {
}
};
struct HybridQueryResult {
int64_t row_num_;
engine::ResultIds id_list_;
engine::ResultDistances distance_list_;
engine::Entity entities_;
};
struct IndexParam {
std::string collection_name_;
int64_t index_type_;
@ -126,6 +134,7 @@ class BaseRequest {
kDeleteByID,
kGetVectorByID,
kGetVectorIDs,
kInsertEntity,
// collection operations
kShowCollections = 300,
@ -136,6 +145,9 @@ class BaseRequest {
kShowCollectionInfo,
kDropCollection,
kPreloadCollection,
kCreateHybridCollection,
kHasHybridCollection,
kDescribeHybridCollection,
// partition operations
kCreatePartition = 400,
@ -151,6 +163,7 @@ class BaseRequest {
kSearchByID = 600,
kSearch,
kSearchCombine,
kHybridSearch,
};
protected:

View File

@ -15,8 +15,11 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "context/HybridSearchContext.h"
#include "query/BinaryQuery.h"
#include "tracing/TextMapCarrier.h"
#include "tracing/TracerUtil.h"
#include "utils/Log.h"
@ -759,6 +762,195 @@ GrpcRequestHandler::Compact(::grpc::ServerContext* context, const ::milvus::grpc
return ::grpc::Status::OK;
}
/*******************************************New Interface*********************************************/
::grpc::Status
GrpcRequestHandler::CreateHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::Mapping* request,
::milvus::grpc::Status* response) {
CHECK_NULLPTR_RETURN(request);
std::vector<std::pair<std::string, engine::meta::hybrid::DataType>> field_types;
std::vector<std::pair<std::string, uint64_t>> vector_dimensions;
std::vector<std::pair<std::string, std::string>> field_params;
for (uint64_t i = 0; i < request->fields_size(); ++i) {
if (request->fields(i).type().has_vector_param()) {
auto vector_dimension =
std::make_pair(request->fields(i).name(), request->fields(i).type().vector_param().dimension());
vector_dimensions.emplace_back(vector_dimension);
} else {
auto type = std::make_pair(request->fields(i).name(),
(engine::meta::hybrid::DataType)request->fields(i).type().data_type());
field_types.emplace_back(type);
}
// Currently only one extra_param
if (request->fields(i).extra_params_size() != 0) {
auto extra_params = std::make_pair(request->fields(i).name(), request->fields(i).extra_params(0).value());
field_params.emplace_back(extra_params);
} else {
auto extra_params = std::make_pair(request->fields(i).name(), "");
field_params.emplace_back(extra_params);
}
}
Status status = request_handler_.CreateHybridCollection(GetContext(context), request->collection_name(),
field_types, vector_dimensions, field_params);
SET_RESPONSE(response, status, context);
return ::grpc::Status::OK;
}
::grpc::Status
GrpcRequestHandler::InsertEntity(::grpc::ServerContext* context, const ::milvus::grpc::HInsertParam* request,
::milvus::grpc::HEntityIDs* response) {
CHECK_NULLPTR_RETURN(request);
std::unordered_map<std::string, std::vector<std::string>> attr_values;
std::unordered_map<std::string, engine::VectorsData> vector_datas;
auto attr_size = request->entities().attr_records_size();
for (uint64_t i = 0; i < attr_size; ++i) {
std::vector<std::string> values;
auto record_size = request->entities().attr_records(i).value_size();
values.resize(record_size);
for (uint64_t j = 0; j < record_size; ++j) {
values[j] = request->entities().attr_records(i).value(j);
}
attr_values.insert(std::make_pair(request->entities().field_names(i), values));
}
auto vector_size = request->entities().result_values_size();
for (uint64_t i = 0; i < vector_size; ++i) {
engine::VectorsData vectors;
CopyRowRecords(request->entities().result_values(i).vector_value().value(), request->entity_id_array(),
vectors);
vector_datas.insert(std::make_pair(request->entities().field_names(attr_size + i), vectors));
}
std::string collection_name = request->collection_name();
std::string partition_tag = request->partition_tag();
Status status =
request_handler_.InsertEntity(GetContext(context), collection_name, partition_tag, attr_values, vector_datas);
response->mutable_entity_id_array()->Resize(static_cast<int>(vector_datas.begin()->second.id_array_.size()), 0);
memcpy(response->mutable_entity_id_array()->mutable_data(), vector_datas.begin()->second.id_array_.data(),
vector_datas.begin()->second.id_array_.size() * sizeof(int64_t));
SET_RESPONSE(response->mutable_status(), status, context);
return ::grpc::Status::OK;
}
void
DeSerialization(const ::milvus::grpc::GeneralQuery& general_query, query::BooleanQueryPtr boolean_clause) {
if (general_query.has_boolean_query()) {
// boolean_clause->SetOccur((query::Occur)general_query.boolean_query().occur());
for (uint64_t i = 0; i < general_query.boolean_query().general_query_size(); ++i) {
if (general_query.boolean_query().general_query(i).has_boolean_query()) {
query::BooleanQueryPtr query =
std::make_shared<query::BooleanQuery>((query::Occur)(general_query.boolean_query().occur()));
DeSerialization(general_query.boolean_query().general_query(i), query);
boolean_clause->AddBooleanQuery(query);
} else {
auto leaf_query = std::make_shared<query::LeafQuery>();
auto query = general_query.boolean_query().general_query(i);
if (query.has_term_query()) {
query::TermQueryPtr term_query = std::make_shared<query::TermQuery>();
term_query->field_name = query.term_query().field_name();
term_query->boost = query.term_query().boost();
term_query->field_value.resize(query.term_query().values_size());
for (uint64_t j = 0; j < query.term_query().values_size(); ++j) {
term_query->field_value[j] = query.term_query().values(j);
}
leaf_query->term_query = term_query;
boolean_clause->AddLeafQuery(leaf_query);
}
if (query.has_range_query()) {
query::RangeQueryPtr range_query = std::make_shared<query::RangeQuery>();
range_query->field_name = query.range_query().field_name();
range_query->boost = query.range_query().boost();
range_query->compare_expr.resize(query.range_query().operand_size());
for (uint64_t j = 0; j < query.range_query().operand_size(); ++j) {
range_query->compare_expr[j].compare_operator =
query::CompareOperator(query.range_query().operand(j).operator_());
range_query->compare_expr[j].operand = query.range_query().operand(j).operand();
}
leaf_query->range_query = range_query;
boolean_clause->AddLeafQuery(leaf_query);
}
if (query.has_vector_query()) {
query::VectorQueryPtr vector_query = std::make_shared<query::VectorQuery>();
engine::VectorsData vectors;
CopyRowRecords(query.vector_query().records(),
google::protobuf::RepeatedField<google::protobuf::int64>(), vectors);
vector_query->query_vector.float_data = vectors.float_data_;
vector_query->query_vector.binary_data = vectors.binary_data_;
vector_query->boost = query.vector_query().query_boost();
vector_query->field_name = query.vector_query().field_name();
vector_query->topk = query.vector_query().topk();
milvus::json json_params;
for (int j = 0; j < query.vector_query().extra_params_size(); j++) {
const ::milvus::grpc::KeyValuePair& extra = query.vector_query().extra_params(j);
if (extra.key() == EXTRA_PARAM_KEY) {
json_params = json::parse(extra.value());
}
}
vector_query->extra_params = json_params;
leaf_query->vector_query = vector_query;
boolean_clause->AddLeafQuery(leaf_query);
}
}
}
}
}
::grpc::Status
GrpcRequestHandler::HybridSearch(::grpc::ServerContext* context, const ::milvus::grpc::HSearchParam* request,
::milvus::grpc::TopKQueryResult* response) {
CHECK_NULLPTR_RETURN(request);
context::HybridSearchContextPtr hybrid_search_context = std::make_shared<context::HybridSearchContext>();
query::BooleanQueryPtr boolean_query = std::make_shared<query::BooleanQuery>();
DeSerialization(request->general_query(), boolean_query);
query::GeneralQueryPtr general_query = std::make_shared<query::GeneralQuery>();
general_query->bin = std::make_shared<query::BinaryQuery>();
query::GenBinaryQuery(boolean_query, general_query->bin);
Status status;
if (!query::ValidateBinaryQuery(general_query->bin)) {
status = Status{SERVER_INVALID_BINARY_QUERY, "Generate wrong binary query tree"};
SET_RESPONSE(response->mutable_status(), status, context);
return ::grpc::Status::OK;
}
hybrid_search_context->general_query_ = general_query;
std::vector<std::string> partition_list;
partition_list.resize(request->partition_tag_array_size());
for (uint64_t i = 0; i < request->partition_tag_array_size(); ++i) {
partition_list[i] = request->partition_tag_array(i);
}
TopKQueryResult result;
status = request_handler_.HybridSearch(GetContext(context), hybrid_search_context, request->collection_name(),
partition_list, general_query, result);
// step 6: construct and return result
ConstructResults(result, response);
SET_RESPONSE(response->mutable_status(), status, context);
return ::grpc::Status::OK;
}
} // namespace grpc
} // namespace server
} // namespace milvus

View File

@ -304,6 +304,76 @@ class GrpcRequestHandler final : public ::milvus::grpc::MilvusService::Service,
Compact(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request,
::milvus::grpc::Status* response);
/*******************************************New Interface*********************************************/
::grpc::Status
CreateHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::Mapping* request,
::milvus::grpc::Status* response) override;
// ::grpc::Status
// HasCollection(::grpc::ServerContext* context,
// const ::milvus::grpc::CollectionName* request,
// ::milvus::grpc::BoolReply* response) override;
//
// ::grpc::Status
// DropCollection(::grpc::ServerContext* context,
// const ::milvus::grpc::CollectionName* request,
// ::milvus::grpc::Status* response) override;
//
// ::grpc::Status
// DescribeCollection(::grpc::ServerContext* context,
// const ::milvus::grpc::CollectionName* request,
// ::milvus::grpc::Mapping* response) override;
//
// ::grpc::Status
// CountCollection(::grpc::ServerContext* context,
// const ::milvus::grpc::CollectionName* request,
// ::milvus::grpc::CollectionRowCount* response) override;
//
// ::grpc::Status
// ShowCollections(::grpc::ServerContext* context,
// const ::milvus::grpc::Command* request,
// ::milvus::grpc::MappingList* response) override;
//
// ::grpc::Status
// ShowCollectionInfo(::grpc::ServerContext* context,
// const ::milvus::grpc::CollectionName* request,
// ::milvus::grpc::CollectionInfo* response) override;
//
// ::grpc::Status
// PreloadCollection(::grpc::ServerContext* context,
// const ::milvus::grpc::CollectionName* request,
// ::milvus::grpc::Status* response) override;
//
::grpc::Status
InsertEntity(::grpc::ServerContext* context, const ::milvus::grpc::HInsertParam* request,
::milvus::grpc::HEntityIDs* response) override;
::grpc::Status
HybridSearch(::grpc::ServerContext* context, const ::milvus::grpc::HSearchParam* request,
::milvus::grpc::TopKQueryResult* response) override;
//
// ::grpc::Status
// HybridSearchInSegments(::grpc::ServerContext* context,
// const ::milvus::
// grpc::HSearchInSegmentsParam* request,
// ::milvus::grpc::HQueryResult* response) override;
//
// ::grpc::Status
// GetEntityByID(::grpc::ServerContext* context,
// const ::milvus::grpc::HEntityIdentity* request,
// ::milvus::grpc::HEntity* response) override;
//
// ::grpc::Status
// GetEntityIDs(::grpc::ServerContext* context,
// const ::milvus::grpc::HGetEntityIDsParam* request,
// ::milvus::grpc::HEntityIDs* response) override;
//
// ::grpc::Status
// DeleteEntitiesByID(::grpc::ServerContext* context,
// const ::milvus::grpc::HDeleteByIDParam* request,
// ::milvus::grpc::Status* response) override;
GrpcRequestHandler&
RegisterRequestHandler(const RequestHandler& handler) {
request_handler_ = handler;

View File

@ -83,6 +83,7 @@ constexpr ErrorCode SERVER_INVALID_INDEX_METRIC_TYPE = ToServerErrorCode(115);
constexpr ErrorCode SERVER_INVALID_INDEX_FILE_SIZE = ToServerErrorCode(116);
constexpr ErrorCode SERVER_OUT_OF_MEMORY = ToServerErrorCode(117);
constexpr ErrorCode SERVER_INVALID_PARTITION_TAG = ToServerErrorCode(118);
constexpr ErrorCode SERVER_INVALID_BINARY_QUERY = ToServerErrorCode(119);
// db error code
constexpr ErrorCode DB_META_TRANSACTION_FAILED = ToDbErrorCode(1);

View File

@ -29,6 +29,8 @@ aux_source_directory(${MILVUS_ENGINE_SRC}/db/engine db_engine_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/db/insert db_insert_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/db/meta db_meta_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/db/wal db_wal_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/search search_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/query query_files)
set(grpc_service_files
${MILVUS_ENGINE_SRC}/grpc/gen-milvus/milvus.grpc.pb.cc
@ -89,10 +91,12 @@ set(web_server_files
aux_source_directory(${MILVUS_ENGINE_SRC}/server/delivery server_delivery_impl_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/server/delivery/request server_delivery_request_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/server/delivery/hybrid_request server_delivery_hybrid_request_files)
aux_source_directory(${MILVUS_ENGINE_SRC}/server/delivery/strategy server_delivery_strategy_files)
set(server_delivery_files
${server_delivery_impl_files}
${server_delivery_request_files}
${server_delivery_hybrid_request_files}
${server_delivery_strategy_files})
aux_source_directory(${MILVUS_ENGINE_SRC}/utils utils_files)
@ -147,6 +151,8 @@ set(common_files
${codecs_files}
${codecs_default_files}
${segment_files}
${search_files}
${query_files}
)
set(unittest_libs

View File

@ -13,6 +13,7 @@
set(test_files
${CMAKE_CURRENT_SOURCE_DIR}/test_db.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_hybrid_db.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_db_mysql.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_wal.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_engine.cpp

View File

@ -0,0 +1,283 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#include <fiu-control.h>
#include <fiu-local.h>
#include <gtest/gtest.h>
#include <boost/filesystem.hpp>
#include <random>
#include <thread>
#include "cache/CpuCacheMgr.h"
#include "config/Config.h"
#include "db/Constants.h"
#include "db/DB.h"
#include "db/DBFactory.h"
#include "db/DBImpl.h"
#include "db/IDGenerator.h"
#include "db/meta/MetaConsts.h"
#include "db/utils.h"
#include "utils/CommonUtil.h"
namespace {
static const char* TABLE_NAME = "test_hybrid";
static constexpr int64_t TABLE_DIM = 128;
static constexpr int64_t SECONDS_EACH_HOUR = 3600;
static constexpr int64_t FIELD_NUM = 4;
static constexpr int64_t NQ = 10;
static constexpr int64_t TOPK = 100;
void
BuildTableSchema(milvus::engine::meta::CollectionSchema& collection_schema,
milvus::engine::meta::hybrid::FieldsSchema& fields_schema,
std::unordered_map<std::string, milvus::engine::meta::hybrid::DataType>& attr_type) {
collection_schema.dimension_ = TABLE_DIM;
collection_schema.collection_id_ = TABLE_NAME;
std::vector<milvus::engine::meta::hybrid::FieldSchema> fields;
fields.resize(FIELD_NUM);
for (uint64_t i = 0; i < FIELD_NUM; ++i) {
fields[i].collection_id_ = TABLE_NAME;
fields[i].field_name_ = "field_" + std::to_string(i + 1);
}
fields[0].field_type_ = (int)milvus::engine::meta::hybrid::DataType::INT32;
fields[1].field_type_ = (int)milvus::engine::meta::hybrid::DataType::INT64;
fields[2].field_type_ = (int)milvus::engine::meta::hybrid::DataType::FLOAT;
fields[3].field_type_ = (int)milvus::engine::meta::hybrid::DataType::VECTOR;
fields_schema.fields_schema_ = fields;
attr_type.insert(std::make_pair("field_0", milvus::engine::meta::hybrid::DataType::INT32));
attr_type.insert(std::make_pair("field_1", milvus::engine::meta::hybrid::DataType::INT64));
attr_type.insert(std::make_pair("field_2", milvus::engine::meta::hybrid::DataType::FLOAT));
}
void
BuildVectors(uint64_t n, uint64_t batch_index, milvus::engine::VectorsData& vectors) {
vectors.vector_count_ = n;
vectors.float_data_.clear();
vectors.float_data_.resize(n * TABLE_DIM);
float* data = vectors.float_data_.data();
for (uint64_t i = 0; i < n; i++) {
for (int64_t j = 0; j < TABLE_DIM; j++) data[TABLE_DIM * i + j] = drand48();
data[TABLE_DIM * i] += i / 2000.;
vectors.id_array_.push_back(n * batch_index + i);
}
}
void
BuildEntity(uint64_t n, uint64_t batch_index, milvus::engine::Entity& entity) {
milvus::engine::VectorsData vectors;
vectors.vector_count_ = n;
vectors.float_data_.clear();
vectors.float_data_.resize(n * TABLE_DIM);
float* data = vectors.float_data_.data();
for (uint64_t i = 0; i < n; i++) {
for (int64_t j = 0; j < TABLE_DIM; j++) data[TABLE_DIM * i + j] = drand48();
data[TABLE_DIM * i] += i / 2000.;
vectors.id_array_.push_back(n * batch_index + i);
}
entity.vector_data_.insert(std::make_pair("field_3", vectors));
std::vector<std::string> value_0, value_1, value_2;
value_0.resize(n);
value_1.resize(n);
value_2.resize(n);
for (uint64_t i = 0; i < n; ++i) {
value_0[i] = std::to_string(i);
value_1[i] = std::to_string(i + n);
value_2[i] = std::to_string((i + 100) / (n + 1));
}
entity.entity_count_ = n;
entity.attr_data_.insert(std::make_pair("field_0", value_0));
entity.attr_data_.insert(std::make_pair("field_1", value_1));
entity.attr_data_.insert(std::make_pair("field_2", value_2));
}
void
ConstructGeneralQuery(milvus::query::GeneralQueryPtr& general_query) {
general_query->bin->relation = milvus::query::QueryRelation::AND;
general_query->bin->left_query = std::make_shared<milvus::query::GeneralQuery>();
general_query->bin->right_query = std::make_shared<milvus::query::GeneralQuery>();
auto left = general_query->bin->left_query;
auto right = general_query->bin->right_query;
left->bin->relation = milvus::query::QueryRelation::AND;
auto term_query = std::make_shared<milvus::query::TermQuery>();
term_query->field_name = "field_0";
term_query->field_value = {"10", "20", "30", "40", "50"};
term_query->boost = 1;
auto range_query = std::make_shared<milvus::query::RangeQuery>();
range_query->field_name = "field_1";
std::vector<milvus::query::CompareExpr> compare_expr;
compare_expr.resize(2);
compare_expr[0].compare_operator = milvus::query::CompareOperator::GTE;
compare_expr[0].operand = "1000";
compare_expr[1].compare_operator = milvus::query::CompareOperator::LTE;
compare_expr[1].operand = "5000";
range_query->compare_expr = compare_expr;
range_query->boost = 2;
auto vector_query = std::make_shared<milvus::query::VectorQuery>();
vector_query->field_name = "field_3";
vector_query->topk = 100;
vector_query->boost = 3;
milvus::json json_params = {{"nprobe", 10}};
vector_query->extra_params = json_params;
milvus::query::VectorRecord record;
record.float_data.resize(NQ * TABLE_DIM);
float* data = record.float_data.data();
for (uint64_t i = 0; i < NQ; i++) {
for (int64_t j = 0; j < TABLE_DIM; j++) data[TABLE_DIM * i + j] = drand48();
data[TABLE_DIM * i] += i / 2000.;
}
vector_query->query_vector = record;
left->bin->left_query = std::make_shared<milvus::query::GeneralQuery>();
left->bin->right_query = std::make_shared<milvus::query::GeneralQuery>();
left->bin->left_query->leaf = std::make_shared<milvus::query::LeafQuery>();
left->bin->right_query->leaf = std::make_shared<milvus::query::LeafQuery>();
left->bin->left_query->leaf->term_query = term_query;
left->bin->right_query->leaf->range_query = range_query;
right->leaf = std::make_shared<milvus::query::LeafQuery>();
right->leaf->vector_query = vector_query;
}
} // namespace
TEST_F(DBTest, HYBRID_DB_TEST) {
milvus::engine::meta::CollectionSchema collection_info;
milvus::engine::meta::hybrid::FieldsSchema fields_info;
std::unordered_map<std::string, milvus::engine::meta::hybrid::DataType> attr_type;
BuildTableSchema(collection_info, fields_info, attr_type);
auto stat = db_->CreateHybridCollection(collection_info, fields_info);
ASSERT_TRUE(stat.ok());
milvus::engine::meta::CollectionSchema collection_info_get;
milvus::engine::meta::hybrid::FieldsSchema fields_info_get;
collection_info_get.collection_id_ = TABLE_NAME;
stat = db_->DescribeHybridCollection(collection_info_get, fields_info_get);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(collection_info_get.dimension_, TABLE_DIM);
uint64_t qb = 1000;
milvus::engine::Entity entity;
BuildEntity(qb, 0, entity);
stat = db_->InsertEntities(TABLE_NAME, "", entity, attr_type);
ASSERT_TRUE(stat.ok());
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
// milvus::engine::CollectionIndex index;
// index.engine_type_ = (int)milvus::engine::EngineType::FAISS_IDMAP;
// index.extra_params_ = {{"nlist", 16384}};
//
// stat = db_->CreateIndex(TABLE_NAME, index);
// ASSERT_TRUE(stat.ok());
}
TEST_F(DBTest, HYBRID_SEARCH_TEST) {
//#ifndef MILVUS_GPU_VERSION
milvus::engine::meta::CollectionSchema collection_info;
milvus::engine::meta::hybrid::FieldsSchema fields_info;
std::unordered_map<std::string, milvus::engine::meta::hybrid::DataType> attr_type;
BuildTableSchema(collection_info, fields_info, attr_type);
auto stat = db_->CreateHybridCollection(collection_info, fields_info);
ASSERT_TRUE(stat.ok());
milvus::engine::meta::CollectionSchema collection_info_get;
milvus::engine::meta::hybrid::FieldsSchema fields_info_get;
collection_info_get.collection_id_ = TABLE_NAME;
stat = db_->DescribeHybridCollection(collection_info_get, fields_info_get);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(collection_info_get.dimension_, TABLE_DIM);
uint64_t qb = 1000;
milvus::engine::Entity entity;
BuildEntity(qb, 0, entity);
stat = db_->InsertEntities(TABLE_NAME, "", entity, attr_type);
ASSERT_TRUE(stat.ok());
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
// Construct general query
milvus::query::GeneralQueryPtr general_query = std::make_shared<milvus::query::GeneralQuery>();
ConstructGeneralQuery(general_query);
std::vector<std::string> tags;
milvus::context::HybridSearchContextPtr hybrid_context = std::make_shared<milvus::context::HybridSearchContext>();
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
uint64_t nq;
stat = db_->HybridQuery(dummy_context_, TABLE_NAME, tags, hybrid_context, general_query, attr_type, nq, result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
//#endif
}
TEST_F(DBTest, COMPACT_TEST) {
milvus::engine::meta::CollectionSchema collection_info;
milvus::engine::meta::hybrid::FieldsSchema fields_info;
std::unordered_map<std::string, milvus::engine::meta::hybrid::DataType> attr_type;
BuildTableSchema(collection_info, fields_info, attr_type);
auto stat = db_->CreateHybridCollection(collection_info, fields_info);
ASSERT_TRUE(stat.ok());
milvus::engine::meta::CollectionSchema collection_info_get;
milvus::engine::meta::hybrid::FieldsSchema fields_info_get;
collection_info_get.collection_id_ = TABLE_NAME;
stat = db_->DescribeHybridCollection(collection_info_get, fields_info_get);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(collection_info_get.dimension_, TABLE_DIM);
uint64_t vector_count = 1000;
milvus::engine::Entity entity;
BuildEntity(vector_count, 0, entity);
stat = db_->InsertEntities(TABLE_NAME, "", entity, attr_type);
ASSERT_TRUE(stat.ok());
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
std::vector<milvus::engine::IDNumber> ids_to_delete;
ids_to_delete.emplace_back(entity.id_array_.front());
ids_to_delete.emplace_back(entity.id_array_.back());
stat = db_->DeleteVectors(collection_info.collection_id_, ids_to_delete);
ASSERT_TRUE(stat.ok());
stat = db_->Flush();
ASSERT_TRUE(stat.ok());
stat = db_->Compact(collection_info.collection_id_);
ASSERT_TRUE(stat.ok());
const int topk = 1, nprobe = 1;
milvus::json json_params = {{"nprobe", nprobe}};
std::vector<std::string> tags;
milvus::engine::ResultIds result_ids;
milvus::engine::ResultDistances result_distances;
for (auto& id : ids_to_delete) {
stat = db_->QueryByID(dummy_context_, collection_info.collection_id_, tags, topk, json_params, id, result_ids,
result_distances);
ASSERT_TRUE(stat.ok());
ASSERT_EQ(result_ids[0], -1);
ASSERT_EQ(result_distances[0], std::numeric_limits<float>::max());
}
}

View File

@ -17,10 +17,10 @@
#include "config/Config.h"
#include "server/Server.h"
#include "server/grpc_impl/GrpcRequestHandler.h"
#include "server/delivery/RequestHandler.h"
#include "server/delivery/RequestScheduler.h"
#include "server/delivery/request/BaseRequest.h"
#include "server/delivery/RequestHandler.h"
#include "server/grpc_impl/GrpcRequestHandler.h"
#include "src/version.h"
#include "grpc/gen-milvus/milvus.grpc.pb.h"
@ -28,11 +28,11 @@
#include "scheduler/ResourceFactory.h"
#include "scheduler/SchedInst.h"
#include "server/DBWrapper.h"
#include "utils/CommonUtil.h"
#include "server/grpc_impl/GrpcServer.h"
#include "utils/CommonUtil.h"
#include <fiu-local.h>
#include <fiu-control.h>
#include <fiu-local.h>
namespace {
@ -58,8 +58,7 @@ CopyBinRowRecord(::milvus::grpc::RowRecord* target, const std::vector<uint8_t>&
}
void
SearchFunc(std::shared_ptr<milvus::server::grpc::GrpcRequestHandler> handler,
::grpc::ServerContext* context,
SearchFunc(std::shared_ptr<milvus::server::grpc::GrpcRequestHandler> handler, ::grpc::ServerContext* context,
std::shared_ptr<::milvus::grpc::SearchParam> request,
std::shared_ptr<::milvus::grpc::TopKQueryResult> result) {
handler->Search(context, request.get(), result.get());
@ -439,7 +438,7 @@ TEST_F(RpcHandlerTest, COMBINE_SEARCH_TEST) {
collection_schema.set_collection_name(collection_name);
collection_schema.set_dimension(COLLECTION_DIM);
collection_schema.set_index_file_size(INDEX_FILE_SIZE);
collection_schema.set_metric_type(1); // L2 metric
collection_schema.set_metric_type(1); // L2 metric
::milvus::grpc::Status status;
handler->CreateCollection(&context, &collection_schema, &status);
ASSERT_EQ(status.error_code(), 0);
@ -494,8 +493,7 @@ TEST_F(RpcHandlerTest, COMBINE_SEARCH_TEST) {
for (int i = 0; i < QUERY_COUNT; i++) {
ResultPtr result_ptr = std::make_shared<::milvus::grpc::TopKQueryResult>();
result_array.push_back(result_ptr);
ThreadPtr
thread = std::make_shared<std::thread>(SearchFunc, handler, &context, request_array[i], result_ptr);
ThreadPtr thread = std::make_shared<std::thread>(SearchFunc, handler, &context, request_array[i], result_ptr);
thread_list.emplace_back(thread);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
@ -541,7 +539,7 @@ TEST_F(RpcHandlerTest, COMBINE_SEARCH_BINARY_TEST) {
collection_schema.set_collection_name(collection_name);
collection_schema.set_dimension(COLLECTION_DIM);
collection_schema.set_index_file_size(INDEX_FILE_SIZE);
collection_schema.set_metric_type(5); // tanimoto metric
collection_schema.set_metric_type(5); // tanimoto metric
::milvus::grpc::Status status;
handler->CreateCollection(&context, &collection_schema, &status);
ASSERT_EQ(status.error_code(), 0);
@ -596,8 +594,7 @@ TEST_F(RpcHandlerTest, COMBINE_SEARCH_BINARY_TEST) {
for (int i = 0; i < QUERY_COUNT; i++) {
ResultPtr result_ptr = std::make_shared<::milvus::grpc::TopKQueryResult>();
result_array.push_back(result_ptr);
ThreadPtr
thread = std::make_shared<std::thread>(SearchFunc, handler, &context, request_array[i], result_ptr);
ThreadPtr thread = std::make_shared<std::thread>(SearchFunc, handler, &context, request_array[i], result_ptr);
thread_list.emplace_back(thread);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
@ -955,6 +952,112 @@ TEST_F(RpcHandlerTest, CMD_TEST) {
handler->Cmd(&context, &command, &reply);
}
TEST_F(RpcHandlerTest, HYBRID_TEST) {
::grpc::ServerContext context;
milvus::grpc::Mapping mapping;
milvus::grpc::Status response;
uint64_t row_num = 1000;
uint64_t dimension = 128;
// Create Hybrid Collection
mapping.set_collection_name("test_hybrid");
auto field_0 = mapping.add_fields();
field_0->set_name("field_0");
field_0->mutable_type()->set_data_type(::milvus::grpc::DataType::INT64);
auto field_1 = mapping.add_fields();
field_1->mutable_type()->mutable_vector_param()->set_dimension(128);
field_1->set_name("field_1");
handler->CreateHybridCollection(&context, &mapping, &response);
// Insert Entities
milvus::grpc::HInsertParam insert_param;
milvus::grpc::HEntityIDs entity_ids;
insert_param.set_collection_name("test_hybrid");
std::vector<std::string> numerica_value;
numerica_value.resize(row_num);
for (uint64_t i = 0; i < row_num; i++) {
numerica_value[i] = std::to_string(i);
}
auto entity = insert_param.mutable_entities();
auto field_name_0 = entity->add_field_names();
*field_name_0 = "field_0";
auto field_name_1 = entity->add_field_names();
*field_name_1 = "field_1";
auto records_0 = entity->add_attr_records();
for (auto value : numerica_value) {
auto record = records_0->add_value();
*record = value;
}
std::vector<std::vector<float>> vector_field;
vector_field.resize(row_num);
for (uint64_t i = 0; i < row_num; ++i) {
vector_field[i].resize(dimension);
for (uint64_t j = 0; j < dimension; ++j) {
vector_field[i][j] = (float)((i + 10) / (j + 20));
}
}
auto vector_record = entity->add_result_values();
for (uint64_t i = 0; i < row_num; ++i) {
auto record = vector_record->mutable_vector_value()->add_value();
auto vector_data = record->mutable_float_data();
vector_data->Resize(static_cast<int>(vector_field[i].size()), 0.0);
memcpy(vector_data->mutable_data(), vector_field[i].data(), vector_field[i].size() * sizeof(float));
}
handler->InsertEntity(&context, &insert_param, &entity_ids);
ASSERT_EQ(entity_ids.entity_id_array_size(), row_num);
// TODO(yukun): Hybrid Search
uint64_t nq = 10;
uint64_t topk = 10;
milvus::grpc::HSearchParam search_param;
auto general_query = search_param.mutable_general_query();
auto boolean_query_1 = general_query->mutable_boolean_query();
boolean_query_1->set_occur(milvus::grpc::Occur::MUST);
auto general_query_1 = boolean_query_1->add_general_query();
auto boolean_query_2 = general_query_1->mutable_boolean_query();
auto term_query = boolean_query_2->add_general_query()->mutable_term_query();
term_query->set_field_name("field_0");
for (uint64_t i = 0; i < nq; ++i) {
auto value = std::to_string(i + nq);
auto term = term_query->add_values();
*term = value;
}
auto vector_query = boolean_query_2->add_general_query()->mutable_vector_query();
vector_query->set_field_name("field_1");
vector_query->set_topk(topk);
vector_query->set_query_boost(2);
std::vector<std::vector<float>> query_vector;
query_vector.resize(nq);
for (uint64_t i = 0; i < nq; ++i) {
query_vector[i].resize(dimension);
for (uint64_t j = 0; j < dimension; ++j) {
query_vector[i][j] = (float)((j + 1) / (i + dimension));
}
}
for (auto record : query_vector) {
auto row_record = vector_query->add_records();
CopyRowRecord(row_record, record);
}
auto extra_param = vector_query->add_extra_params();
extra_param->set_key("params");
milvus::json param = {{"nprobe", 16}};
extra_param->set_value(param.dump());
search_param.set_collection_name("test_hybrid");
auto search_extra_param = search_param.add_extra_params();
search_extra_param->set_key("params");
search_extra_param->set_value("");
milvus::grpc::TopKQueryResult topk_query_result;
handler->HybridSearch(&context, &search_param, &topk_query_result);
}
//////////////////////////////////////////////////////////////////////
namespace {
class DummyRequest : public milvus::server::BaseRequest {
@ -1000,8 +1103,7 @@ class AsyncDummyRequest : public milvus::server::BaseRequest {
public:
AsyncDummyRequest()
: BaseRequest(std::make_shared<milvus::server::Context>("dummy_request_id2"),
milvus::server::BaseRequest::kCmd,
: BaseRequest(std::make_shared<milvus::server::Context>("dummy_request_id2"), milvus::server::BaseRequest::kCmd,
true) {
}
};
@ -1012,8 +1114,8 @@ TEST_F(RpcSchedulerTest, BASE_TASK_TEST) {
ASSERT_TRUE(status.ok());
milvus::server::RequestScheduler::GetInstance().Start();
// milvus::server::RequestScheduler::GetInstance().Stop();
// milvus::server::RequestScheduler::GetInstance().Start();
// milvus::server::RequestScheduler::GetInstance().Stop();
// milvus::server::RequestScheduler::GetInstance().Start();
milvus::server::BaseRequestPtr base_task_ptr = DummyRequest::Create();
milvus::server::RequestScheduler::ExecRequest(base_task_ptr);
@ -1025,11 +1127,11 @@ TEST_F(RpcSchedulerTest, BASE_TASK_TEST) {
milvus::server::RequestScheduler::GetInstance().ExecuteRequest(request_ptr);
fiu_disable("RequestScheduler.ExecuteRequest.push_queue_fail");
// std::string dummy2 = "dql2";
// milvus::server::BaseRequestPtr base_task_ptr2 = DummyRequest::Create(dummy2);
// fiu_enable("RequestScheduler.PutToQueue.null_queue", 1, NULL, 0);
// milvus::server::RequestScheduler::GetInstance().ExecuteRequest(base_task_ptr2);
// fiu_disable("RequestScheduler.PutToQueue.null_queue");
// std::string dummy2 = "dql2";
// milvus::server::BaseRequestPtr base_task_ptr2 = DummyRequest::Create(dummy2);
// fiu_enable("RequestScheduler.PutToQueue.null_queue", 1, NULL, 0);
// milvus::server::RequestScheduler::GetInstance().ExecuteRequest(base_task_ptr2);
// fiu_disable("RequestScheduler.PutToQueue.null_queue");
milvus::server::BaseRequestPtr base_task_ptr3 = DummyRequest::Create();
fiu_enable("RequestScheduler.TakeToExecute.throw_std_exception", 1, NULL, 0);
@ -1063,7 +1165,7 @@ TEST_F(RpcSchedulerTest, BASE_TASK_TEST) {
}
TEST(RpcTest, RPC_SERVER_TEST) {
using GrpcServer = milvus::server::grpc::GrpcServer;
using GrpcServer = milvus::server::grpc::GrpcServer;
GrpcServer& server = GrpcServer::GetInstance();
fiu_init(0);

View File

@ -56,7 +56,8 @@ main(int argc, char* argv[]) {
}
ClientTest test(address, port);
test.Test();
// test.Test();
test.TestHybrid();
printf("Client stop...\n");
return 0;

View File

@ -10,6 +10,7 @@
// or implied. See the License for the specific language governing permissions and limitations under the License.
#include "include/MilvusApi.h"
#include "include/BooleanQuery.h"
#include "examples/utils/TimeRecorder.h"
#include "examples/utils/Utils.h"
#include "examples/simple/src/ClientTest.h"
@ -34,6 +35,7 @@ constexpr int64_t SEARCH_TARGET = BATCH_ENTITY_COUNT / 2; // change this value,
constexpr int64_t ADD_ENTITY_LOOP = 5;
constexpr milvus::IndexType INDEX_TYPE = milvus::IndexType::IVFSQ8;
constexpr int32_t NLIST = 16384;
constexpr uint64_t FIELD_NUM = 3;
} // namespace
@ -226,6 +228,86 @@ ClientTest::DropCollection(const std::string& collection_name) {
std::cout << "DropCollection function call status: " << stat.message() << std::endl;
}
void
ClientTest::CreateHybridCollection(const std::string& collection_name) {
milvus::FieldPtr field_ptr1 = std::make_shared<milvus::Field>();
milvus::FieldPtr field_ptr2 = std::make_shared<milvus::Field>();
milvus::VectorFieldPtr vec_field_ptr = std::make_shared<milvus::VectorField>();
field_ptr1->field_type = milvus::DataType::INT64;
field_ptr1->field_name = "field_1";
field_ptr2->field_type = milvus::DataType::FLOAT;
field_ptr2->field_name = "field_2";
vec_field_ptr->field_type = milvus::DataType::VECTOR;
vec_field_ptr->field_name = "field_3";
vec_field_ptr->dimension = 128;
std::vector<milvus::FieldPtr> numerica_fields;
std::vector<milvus::VectorFieldPtr> vector_fields;
numerica_fields.emplace_back(field_ptr1);
numerica_fields.emplace_back(field_ptr2);
vector_fields.emplace_back(vec_field_ptr);
milvus::HMapping mapping = {collection_name, numerica_fields, vector_fields};
milvus::Status stat = conn_->CreateHybridCollection(mapping);
std::cout << "CreateHybridCollection function call status: " << stat.message() << std::endl;
}
void
ClientTest::InsertHybridEntities(std::string& collection_name, int64_t row_num) {
std::unordered_map<std::string, std::vector<std::string>> numerica_value;
std::vector<std::string> value1, value2;
value1.resize(row_num);
value2.resize(row_num);
for (uint64_t i = 0; i < row_num; ++i) {
value1[i] = std::to_string(i);
value2[i] = std::to_string(i + row_num);
}
numerica_value.insert(std::make_pair("field_1", value1));
numerica_value.insert(std::make_pair("field_2", value2));
std::unordered_map<std::string, std::vector<milvus::Entity>> vector_value;
std::vector<milvus::Entity> entity_array;
std::vector<int64_t> record_ids;
{ // generate vectors
milvus_sdk::Utils::BuildEntities(0,
row_num,
entity_array,
record_ids,
128);
}
vector_value.insert(std::make_pair("field_3", entity_array));
milvus::HEntity entity = {numerica_value, vector_value};
std::vector<uint64_t> id_array;
milvus::Status status = conn_->InsertEntity(collection_name, "", entity, id_array);
std::cout << "InsertHybridEntities function call status: " << status.message() << std::endl;
}
void
ClientTest::HybridSearch(std::string& collection_name) {
std::vector<std::string> partition_tags;
milvus::TopKQueryResult topk_query_result;
auto leaf_queries = milvus_sdk::Utils::GenLeafQuery();
//must
auto must_clause = std::make_shared<milvus::BooleanQuery>(milvus::Occur::MUST);
must_clause->AddLeafQuery(leaf_queries[0]);
must_clause->AddLeafQuery(leaf_queries[1]);
must_clause->AddLeafQuery(leaf_queries[2]);
auto query_clause = std::make_shared<milvus::BooleanQuery>();
query_clause->AddBooleanQuery(must_clause);
std::string extra_params;
milvus::Status
status = conn_->HybridSearch(collection_name, partition_tags, query_clause, extra_params, topk_query_result);
for (uint64_t i = 0; i < topk_query_result.size(); ++i) {
std::cout << topk_query_result[i].ids[0] << " --------- " << topk_query_result[i].distances[0] << std::endl;
}
std::cout << "HybridSearch function call status: " << status.message() << std::endl;
}
void
ClientTest::Test() {
std::string collection_name = COLLECTION_NAME;
@ -262,3 +344,13 @@ ClientTest::Test() {
DropIndex(collection_name);
DropCollection(collection_name);
}
void
ClientTest::TestHybrid() {
std::string collection_name = "HYBRID_TEST";
CreateHybridCollection(collection_name);
InsertHybridEntities(collection_name, 1000);
Flush(collection_name);
// SearchEntities(collection_name, )
HybridSearch(collection_name);
}

View File

@ -26,6 +26,9 @@ class ClientTest {
void
Test();
void
TestHybrid();
private:
void
ShowServerVersion();
@ -78,6 +81,17 @@ class ClientTest {
void
DropCollection(const std::string&);
/*******************************New Interface**********************************/
void
CreateHybridCollection(const std::string& collection_name);
void
InsertHybridEntities(std::string&, int64_t);
void
HybridSearch(std::string&);
private:
std::shared_ptr<milvus::Connection> conn_;
std::vector<std::pair<int64_t, milvus::Entity>> search_entity_array_;

View File

@ -140,7 +140,7 @@ Utils::BuildEntities(int64_t from, int64_t to, std::vector<milvus::Entity>& enti
milvus::Entity entity;
entity.float_data.resize(dimension);
for (int64_t i = 0; i < dimension; i++) {
entity.float_data[i] = (float)(k % (i + 1));
entity.float_data[i] = (float)((k + 100) % (i + 1));
}
entity_array.emplace_back(entity);
@ -249,4 +249,62 @@ Utils::PrintCollectionInfo(const milvus::CollectionInfo& info) {
BLOCK_SPLITER
}
void ConstructVector(uint64_t nq, uint64_t dimension, std::vector<milvus::Entity>& query_vector) {
query_vector.resize(nq);
for (uint64_t i = 0; i < nq; ++i) {
query_vector[i].float_data.resize(dimension);
for (uint64_t j = 0; j < dimension; ++j) {
query_vector[i].float_data[j] = (float)((i + 100) / (j + 1));
}
}
}
std::vector<milvus::LeafQueryPtr>
Utils::GenLeafQuery() {
//Construct TermQuery
std::vector<std::string> field_value;
field_value.resize(1000);
for (uint64_t i = 0; i < 1000; ++i) {
field_value[i] = std::to_string(i);
}
milvus::TermQueryPtr tq = std::make_shared<milvus::TermQuery>();
tq->field_name = "field_1";
tq->field_value = field_value;
//Construct RangeQuery
milvus::CompareExpr ce1 = {milvus::CompareOperator::LTE, "10000"}, ce2 = {milvus::CompareOperator::GTE, "1"};
std::vector<milvus::CompareExpr> ces{ce1, ce2};
milvus::RangeQueryPtr rq = std::make_shared<milvus::RangeQuery>();
rq->field_name = "field_2";
rq->compare_expr = ces;
//Construct VectorQuery
uint64_t NQ = 10;
uint64_t DIMENSION = 128;
uint64_t NPROBE = 32;
milvus::VectorQueryPtr vq = std::make_shared<milvus::VectorQuery>();
ConstructVector(NQ, DIMENSION, vq->query_vector);
vq->field_name = "field_3";
vq->topk = 10;
JSON json_params = {{"nprobe", NPROBE}};
vq->extra_params = json_params.dump();
std::vector<milvus::LeafQueryPtr> lq;
milvus::LeafQueryPtr lq1 = std::make_shared<milvus::LeafQuery>();
milvus::LeafQueryPtr lq2 = std::make_shared<milvus::LeafQuery>();
milvus::LeafQueryPtr lq3 = std::make_shared<milvus::LeafQuery>();
lq.emplace_back(lq1);
lq.emplace_back(lq2);
lq.emplace_back(lq3);
lq1->term_query_ptr = tq;
lq2->range_query_ptr = rq;
lq3->vector_query_ptr = vq;
lq1->query_boost = 1.0;
lq2->query_boost = 2.0;
lq3->query_boost = 3.0;
return lq;
}
} // namespace milvus_sdk

View File

@ -12,6 +12,7 @@
#pragma once
#include "MilvusApi.h"
#include "BooleanQuery.h"
#include "thirdparty/nlohmann/json.hpp"
#include <memory>
@ -72,6 +73,9 @@ class Utils {
static void
PrintCollectionInfo(const milvus::CollectionInfo& collection_info);
static std::vector<milvus::LeafQueryPtr>
GenLeafQuery();
};
} // namespace milvus_sdk

View File

@ -44,6 +44,20 @@ static const char* MilvusService_method_names[] = {
"/milvus.grpc.MilvusService/PreloadCollection",
"/milvus.grpc.MilvusService/Flush",
"/milvus.grpc.MilvusService/Compact",
"/milvus.grpc.MilvusService/CreateHybridCollection",
"/milvus.grpc.MilvusService/HasHybridCollection",
"/milvus.grpc.MilvusService/DropHybridCollection",
"/milvus.grpc.MilvusService/DescribeHybridCollection",
"/milvus.grpc.MilvusService/CountHybridCollection",
"/milvus.grpc.MilvusService/ShowHybridCollections",
"/milvus.grpc.MilvusService/ShowHybridCollectionInfo",
"/milvus.grpc.MilvusService/PreloadHybridCollection",
"/milvus.grpc.MilvusService/InsertEntity",
"/milvus.grpc.MilvusService/HybridSearch",
"/milvus.grpc.MilvusService/HybridSearchInSegments",
"/milvus.grpc.MilvusService/GetEntityByID",
"/milvus.grpc.MilvusService/GetEntityIDs",
"/milvus.grpc.MilvusService/DeleteEntitiesByID",
};
std::unique_ptr< MilvusService::Stub> MilvusService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
@ -77,6 +91,20 @@ MilvusService::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& chan
, rpcmethod_PreloadCollection_(MilvusService_method_names[21], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Flush_(MilvusService_method_names[22], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_Compact_(MilvusService_method_names[23], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CreateHybridCollection_(MilvusService_method_names[24], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HasHybridCollection_(MilvusService_method_names[25], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DropHybridCollection_(MilvusService_method_names[26], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DescribeHybridCollection_(MilvusService_method_names[27], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_CountHybridCollection_(MilvusService_method_names[28], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowHybridCollections_(MilvusService_method_names[29], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_ShowHybridCollectionInfo_(MilvusService_method_names[30], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_PreloadHybridCollection_(MilvusService_method_names[31], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_InsertEntity_(MilvusService_method_names[32], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HybridSearch_(MilvusService_method_names[33], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_HybridSearchInSegments_(MilvusService_method_names[34], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetEntityByID_(MilvusService_method_names[35], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_GetEntityIDs_(MilvusService_method_names[36], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
, rpcmethod_DeleteEntitiesByID_(MilvusService_method_names[37], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
{}
::grpc::Status MilvusService::Stub::CreateCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionSchema& request, ::milvus::grpc::Status* response) {
@ -751,6 +779,398 @@ void MilvusService::Stub::experimental_async::Compact(::grpc::ClientContext* con
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_Compact_, context, request, false);
}
::grpc::Status MilvusService::Stub::CreateHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::Mapping& request, ::milvus::grpc::Status* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_CreateHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::CreateHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::Mapping* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_CreateHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::CreateHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_CreateHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::CreateHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::Mapping* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_CreateHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::CreateHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_CreateHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::AsyncCreateHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::Mapping& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_CreateHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::PrepareAsyncCreateHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::Mapping& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_CreateHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::HasHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::BoolReply* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_HasHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::HasHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::BoolReply* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HasHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HasHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::BoolReply* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HasHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HasHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::BoolReply* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HasHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::HasHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::BoolReply* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HasHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::BoolReply>* MilvusService::Stub::AsyncHasHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::BoolReply>::Create(channel_.get(), cq, rpcmethod_HasHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::BoolReply>* MilvusService::Stub::PrepareAsyncHasHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::BoolReply>::Create(channel_.get(), cq, rpcmethod_HasHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::DropHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::Status* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_DropHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::DropHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DropHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DropHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DropHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DropHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DropHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::DropHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DropHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::AsyncDropHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_DropHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::PrepareAsyncDropHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_DropHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::DescribeHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::Mapping* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_DescribeHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::DescribeHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Mapping* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DescribeHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DescribeHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Mapping* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DescribeHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DescribeHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Mapping* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DescribeHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::DescribeHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Mapping* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DescribeHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Mapping>* MilvusService::Stub::AsyncDescribeHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Mapping>::Create(channel_.get(), cq, rpcmethod_DescribeHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Mapping>* MilvusService::Stub::PrepareAsyncDescribeHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Mapping>::Create(channel_.get(), cq, rpcmethod_DescribeHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::CountHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::CollectionRowCount* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_CountHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::CountHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionRowCount* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_CountHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::CountHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::CollectionRowCount* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_CountHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::CountHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionRowCount* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_CountHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::CountHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::CollectionRowCount* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_CountHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::CollectionRowCount>* MilvusService::Stub::AsyncCountHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::CollectionRowCount>::Create(channel_.get(), cq, rpcmethod_CountHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::CollectionRowCount>* MilvusService::Stub::PrepareAsyncCountHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::CollectionRowCount>::Create(channel_.get(), cq, rpcmethod_CountHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::ShowHybridCollections(::grpc::ClientContext* context, const ::milvus::grpc::Command& request, ::milvus::grpc::MappingList* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_ShowHybridCollections_, context, request, response);
}
void MilvusService::Stub::experimental_async::ShowHybridCollections(::grpc::ClientContext* context, const ::milvus::grpc::Command* request, ::milvus::grpc::MappingList* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollections_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::ShowHybridCollections(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::MappingList* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollections_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::ShowHybridCollections(::grpc::ClientContext* context, const ::milvus::grpc::Command* request, ::milvus::grpc::MappingList* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollections_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::ShowHybridCollections(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::MappingList* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollections_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::MappingList>* MilvusService::Stub::AsyncShowHybridCollectionsRaw(::grpc::ClientContext* context, const ::milvus::grpc::Command& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::MappingList>::Create(channel_.get(), cq, rpcmethod_ShowHybridCollections_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::MappingList>* MilvusService::Stub::PrepareAsyncShowHybridCollectionsRaw(::grpc::ClientContext* context, const ::milvus::grpc::Command& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::MappingList>::Create(channel_.get(), cq, rpcmethod_ShowHybridCollections_, context, request, false);
}
::grpc::Status MilvusService::Stub::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::CollectionInfo* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_ShowHybridCollectionInfo_, context, request, response);
}
void MilvusService::Stub::experimental_async::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionInfo* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollectionInfo_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::CollectionInfo* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollectionInfo_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionInfo* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollectionInfo_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::ShowHybridCollectionInfo(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::CollectionInfo* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ShowHybridCollectionInfo_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::CollectionInfo>* MilvusService::Stub::AsyncShowHybridCollectionInfoRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::CollectionInfo>::Create(channel_.get(), cq, rpcmethod_ShowHybridCollectionInfo_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::CollectionInfo>* MilvusService::Stub::PrepareAsyncShowHybridCollectionInfoRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::CollectionInfo>::Create(channel_.get(), cq, rpcmethod_ShowHybridCollectionInfo_, context, request, false);
}
::grpc::Status MilvusService::Stub::PreloadHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::milvus::grpc::Status* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_PreloadHybridCollection_, context, request, response);
}
void MilvusService::Stub::experimental_async::PreloadHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_PreloadHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::PreloadHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_PreloadHybridCollection_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::PreloadHybridCollection(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_PreloadHybridCollection_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::PreloadHybridCollection(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_PreloadHybridCollection_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::AsyncPreloadHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_PreloadHybridCollection_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::PrepareAsyncPreloadHybridCollectionRaw(::grpc::ClientContext* context, const ::milvus::grpc::CollectionName& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_PreloadHybridCollection_, context, request, false);
}
::grpc::Status MilvusService::Stub::InsertEntity(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam& request, ::milvus::grpc::HEntityIDs* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_InsertEntity_, context, request, response);
}
void MilvusService::Stub::experimental_async::InsertEntity(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam* request, ::milvus::grpc::HEntityIDs* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_InsertEntity_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::InsertEntity(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntityIDs* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_InsertEntity_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::InsertEntity(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam* request, ::milvus::grpc::HEntityIDs* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_InsertEntity_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::InsertEntity(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntityIDs* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_InsertEntity_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntityIDs>* MilvusService::Stub::AsyncInsertEntityRaw(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntityIDs>::Create(channel_.get(), cq, rpcmethod_InsertEntity_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntityIDs>* MilvusService::Stub::PrepareAsyncInsertEntityRaw(::grpc::ClientContext* context, const ::milvus::grpc::HInsertParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntityIDs>::Create(channel_.get(), cq, rpcmethod_InsertEntity_, context, request, false);
}
::grpc::Status MilvusService::Stub::HybridSearch(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam& request, ::milvus::grpc::TopKQueryResult* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_HybridSearch_, context, request, response);
}
void MilvusService::Stub::experimental_async::HybridSearch(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam* request, ::milvus::grpc::TopKQueryResult* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HybridSearch_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HybridSearch(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::TopKQueryResult* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HybridSearch_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HybridSearch(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam* request, ::milvus::grpc::TopKQueryResult* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HybridSearch_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::HybridSearch(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::TopKQueryResult* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HybridSearch_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::TopKQueryResult>* MilvusService::Stub::AsyncHybridSearchRaw(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::TopKQueryResult>::Create(channel_.get(), cq, rpcmethod_HybridSearch_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::TopKQueryResult>* MilvusService::Stub::PrepareAsyncHybridSearchRaw(::grpc::ClientContext* context, const ::milvus::grpc::HSearchParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::TopKQueryResult>::Create(channel_.get(), cq, rpcmethod_HybridSearch_, context, request, false);
}
::grpc::Status MilvusService::Stub::HybridSearchInSegments(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam& request, ::milvus::grpc::TopKQueryResult* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_HybridSearchInSegments_, context, request, response);
}
void MilvusService::Stub::experimental_async::HybridSearchInSegments(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam* request, ::milvus::grpc::TopKQueryResult* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HybridSearchInSegments_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HybridSearchInSegments(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::TopKQueryResult* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_HybridSearchInSegments_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::HybridSearchInSegments(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam* request, ::milvus::grpc::TopKQueryResult* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HybridSearchInSegments_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::HybridSearchInSegments(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::TopKQueryResult* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_HybridSearchInSegments_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::TopKQueryResult>* MilvusService::Stub::AsyncHybridSearchInSegmentsRaw(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::TopKQueryResult>::Create(channel_.get(), cq, rpcmethod_HybridSearchInSegments_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::TopKQueryResult>* MilvusService::Stub::PrepareAsyncHybridSearchInSegmentsRaw(::grpc::ClientContext* context, const ::milvus::grpc::HSearchInSegmentsParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::TopKQueryResult>::Create(channel_.get(), cq, rpcmethod_HybridSearchInSegments_, context, request, false);
}
::grpc::Status MilvusService::Stub::GetEntityByID(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity& request, ::milvus::grpc::HEntity* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetEntityByID_, context, request, response);
}
void MilvusService::Stub::experimental_async::GetEntityByID(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity* request, ::milvus::grpc::HEntity* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetEntityByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetEntityByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntity* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetEntityByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetEntityByID(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity* request, ::milvus::grpc::HEntity* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetEntityByID_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::GetEntityByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntity* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetEntityByID_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntity>* MilvusService::Stub::AsyncGetEntityByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntity>::Create(channel_.get(), cq, rpcmethod_GetEntityByID_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntity>* MilvusService::Stub::PrepareAsyncGetEntityByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::HEntityIdentity& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntity>::Create(channel_.get(), cq, rpcmethod_GetEntityByID_, context, request, false);
}
::grpc::Status MilvusService::Stub::GetEntityIDs(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam& request, ::milvus::grpc::HEntityIDs* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_GetEntityIDs_, context, request, response);
}
void MilvusService::Stub::experimental_async::GetEntityIDs(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam* request, ::milvus::grpc::HEntityIDs* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetEntityIDs_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetEntityIDs(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntityIDs* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_GetEntityIDs_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::GetEntityIDs(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam* request, ::milvus::grpc::HEntityIDs* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetEntityIDs_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::GetEntityIDs(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::HEntityIDs* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_GetEntityIDs_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntityIDs>* MilvusService::Stub::AsyncGetEntityIDsRaw(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntityIDs>::Create(channel_.get(), cq, rpcmethod_GetEntityIDs_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::HEntityIDs>* MilvusService::Stub::PrepareAsyncGetEntityIDsRaw(::grpc::ClientContext* context, const ::milvus::grpc::HGetEntityIDsParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::HEntityIDs>::Create(channel_.get(), cq, rpcmethod_GetEntityIDs_, context, request, false);
}
::grpc::Status MilvusService::Stub::DeleteEntitiesByID(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam& request, ::milvus::grpc::Status* response) {
return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_DeleteEntitiesByID_, context, request, response);
}
void MilvusService::Stub::experimental_async::DeleteEntitiesByID(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DeleteEntitiesByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DeleteEntitiesByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, std::function<void(::grpc::Status)> f) {
::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DeleteEntitiesByID_, context, request, response, std::move(f));
}
void MilvusService::Stub::experimental_async::DeleteEntitiesByID(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DeleteEntitiesByID_, context, request, response, reactor);
}
void MilvusService::Stub::experimental_async::DeleteEntitiesByID(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::milvus::grpc::Status* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DeleteEntitiesByID_, context, request, response, reactor);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::AsyncDeleteEntitiesByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_DeleteEntitiesByID_, context, request, true);
}
::grpc::ClientAsyncResponseReader< ::milvus::grpc::Status>* MilvusService::Stub::PrepareAsyncDeleteEntitiesByIDRaw(::grpc::ClientContext* context, const ::milvus::grpc::HDeleteByIDParam& request, ::grpc::CompletionQueue* cq) {
return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::milvus::grpc::Status>::Create(channel_.get(), cq, rpcmethod_DeleteEntitiesByID_, context, request, false);
}
MilvusService::Service::Service() {
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[0],
@ -872,6 +1292,76 @@ MilvusService::Service::Service() {
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::Compact), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[24],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::Mapping, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::CreateHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[25],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::BoolReply>(
std::mem_fn(&MilvusService::Service::HasHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[26],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::DropHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[27],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Mapping>(
std::mem_fn(&MilvusService::Service::DescribeHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[28],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::CollectionRowCount>(
std::mem_fn(&MilvusService::Service::CountHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[29],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::Command, ::milvus::grpc::MappingList>(
std::mem_fn(&MilvusService::Service::ShowHybridCollections), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[30],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::CollectionInfo>(
std::mem_fn(&MilvusService::Service::ShowHybridCollectionInfo), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[31],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::CollectionName, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::PreloadHybridCollection), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[32],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HInsertParam, ::milvus::grpc::HEntityIDs>(
std::mem_fn(&MilvusService::Service::InsertEntity), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[33],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HSearchParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::HybridSearch), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[34],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HSearchInSegmentsParam, ::milvus::grpc::TopKQueryResult>(
std::mem_fn(&MilvusService::Service::HybridSearchInSegments), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[35],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HEntityIdentity, ::milvus::grpc::HEntity>(
std::mem_fn(&MilvusService::Service::GetEntityByID), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[36],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HGetEntityIDsParam, ::milvus::grpc::HEntityIDs>(
std::mem_fn(&MilvusService::Service::GetEntityIDs), this)));
AddMethod(new ::grpc::internal::RpcServiceMethod(
MilvusService_method_names[37],
::grpc::internal::RpcMethod::NORMAL_RPC,
new ::grpc::internal::RpcMethodHandler< MilvusService::Service, ::milvus::grpc::HDeleteByIDParam, ::milvus::grpc::Status>(
std::mem_fn(&MilvusService::Service::DeleteEntitiesByID), this)));
}
MilvusService::Service::~Service() {
@ -1045,6 +1535,104 @@ MilvusService::Service::~Service() {
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::CreateHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::Mapping* request, ::milvus::grpc::Status* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::HasHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::BoolReply* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::DropHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::DescribeHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Mapping* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::CountHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionRowCount* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::ShowHybridCollections(::grpc::ServerContext* context, const ::milvus::grpc::Command* request, ::milvus::grpc::MappingList* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::ShowHybridCollectionInfo(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::CollectionInfo* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::PreloadHybridCollection(::grpc::ServerContext* context, const ::milvus::grpc::CollectionName* request, ::milvus::grpc::Status* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::InsertEntity(::grpc::ServerContext* context, const ::milvus::grpc::HInsertParam* request, ::milvus::grpc::HEntityIDs* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::HybridSearch(::grpc::ServerContext* context, const ::milvus::grpc::HSearchParam* request, ::milvus::grpc::TopKQueryResult* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::HybridSearchInSegments(::grpc::ServerContext* context, const ::milvus::grpc::HSearchInSegmentsParam* request, ::milvus::grpc::TopKQueryResult* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::GetEntityByID(::grpc::ServerContext* context, const ::milvus::grpc::HEntityIdentity* request, ::milvus::grpc::HEntity* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::GetEntityIDs(::grpc::ServerContext* context, const ::milvus::grpc::HGetEntityIDsParam* request, ::milvus::grpc::HEntityIDs* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
::grpc::Status MilvusService::Service::DeleteEntitiesByID(::grpc::ServerContext* context, const ::milvus::grpc::HDeleteByIDParam* request, ::milvus::grpc::Status* response) {
(void) context;
(void) request;
(void) response;
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
} // namespace milvus
} // namespace grpc

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -574,4 +574,191 @@ ClientProxy::CompactCollection(const std::string& collection_name) {
}
}
/*******************************New Interface**********************************/
Status
ClientProxy::CreateHybridCollection(const HMapping& mapping) {
try {
::milvus::grpc::Mapping grpc_mapping;
grpc_mapping.set_collection_name(mapping.collection_name);
for (auto field : mapping.numerica_fields) {
::milvus::grpc::FieldParam* field_param = grpc_mapping.add_fields();
field_param->set_name(field->field_name);
field_param->mutable_type()->set_data_type((::milvus::grpc::DataType)field->field_type);
::milvus::grpc::KeyValuePair* kv_pair = field_param->add_extra_params();
kv_pair->set_key("params");
kv_pair->set_value(field->extram_params);
}
for (auto field : mapping.vector_fields) {
::milvus::grpc::FieldParam* field_param = grpc_mapping.add_fields();
field_param->set_name(field->field_name);
field_param->mutable_type()->set_data_type((::milvus::grpc::DataType)field->field_type);
field_param->mutable_type()->mutable_vector_param()->set_dimension(field->dimension);
::milvus::grpc::KeyValuePair* kv_pair = field_param->add_extra_params();
kv_pair->set_key("params");
kv_pair->set_value(field->extram_params);
}
return client_ptr_->CreateHybridCollection(grpc_mapping);
} catch (std::exception& exception) {
return Status(StatusCode::UnknownError, "Failed to create collection: " + std::string(exception.what()));
}
}
void
CopyVectorField(::milvus::grpc::RowRecord* target, const Entity& src) {
if (!src.float_data.empty()) {
auto vector_data = target->mutable_float_data();
vector_data->Resize(static_cast<int>(src.float_data.size()), 0.0);
memcpy(vector_data->mutable_data(), src.float_data.data(), src.float_data.size() * sizeof(float));
}
if (!src.binary_data.empty()) {
target->set_binary_data(src.binary_data.data(), src.binary_data.size());
}
}
Status
ClientProxy::InsertEntity(const std::string& collection_name,
const std::string& partition_tag,
HEntity& entities,
std::vector<uint64_t>& id_array) {
Status status;
try {
::milvus::grpc::HInsertParam grpc_param;
grpc_param.set_collection_name(collection_name);
grpc_param.set_partition_tag(partition_tag);
auto numerica_it = entities.numerica_value.begin();
for (; numerica_it != entities.numerica_value.end(); numerica_it++) {
auto name = grpc_param.mutable_entities()->add_field_names();
*name = numerica_it->first;
auto records = grpc_param.mutable_entities()->add_attr_records();
for (auto value : numerica_it->second) {
auto attr = records->add_value();
*attr = value;
}
}
auto vector_it = entities.vector_value.begin();
for (; vector_it != entities.vector_value.end(); vector_it++) {
auto name = grpc_param.mutable_entities()->add_field_names();
*name = vector_it->first;
::milvus::grpc::FieldValue* vector_field = grpc_param.mutable_entities()->add_result_values();
for (auto entity : vector_it->second) {
::milvus::grpc::RowRecord* record = vector_field->mutable_vector_value()->add_value();
CopyVectorField(record, entity);
}
}
::milvus::grpc::HEntityIDs entity_ids;
if (!id_array.empty()) {
auto row_ids = grpc_param.mutable_entity_id_array();
row_ids->Resize(static_cast<int>(id_array.size()), -1);
memcpy(row_ids->mutable_data(), id_array.data(), id_array.size() * sizeof(int64_t));
status = client_ptr_->InsertEntities(grpc_param, entity_ids);
} else {
status = client_ptr_->InsertEntities(grpc_param, entity_ids);
id_array.insert(id_array.end(), entity_ids.entity_id_array().begin(), entity_ids.entity_id_array().end());
}
} catch (std::exception& exception) {
return Status(StatusCode::UnknownError, "Failed to create collection: " + std::string(exception.what()));
}
return status;
}
void
WriteQueryToProto(::milvus::grpc::GeneralQuery* general_query, BooleanQueryPtr boolean_query) {
if (!boolean_query->GetBooleanQueries().empty()) {
for (auto query : boolean_query->GetBooleanQueries()) {
auto grpc_boolean_query = general_query->mutable_boolean_query();
grpc_boolean_query->set_occur((::milvus::grpc::Occur)query->GetOccur());
::milvus::grpc::GeneralQuery* next_query = grpc_boolean_query->add_general_query();
WriteQueryToProto(next_query, query);
}
} else {
for (auto leaf_query : boolean_query->GetLeafQueries()) {
::milvus::grpc::GeneralQuery* grpc_query = general_query->mutable_boolean_query()->add_general_query();
if (leaf_query->term_query_ptr != nullptr) {
auto term_query = grpc_query->mutable_term_query();
term_query->set_field_name(leaf_query->term_query_ptr->field_name);
term_query->set_boost(leaf_query->query_boost);
for (auto field_value : leaf_query->term_query_ptr->field_value) {
auto value = term_query->add_values();
*value = field_value;
}
}
if (leaf_query->range_query_ptr != nullptr) {
auto range_query = grpc_query->mutable_range_query();
range_query->set_boost(leaf_query->query_boost);
range_query->set_field_name(leaf_query->range_query_ptr->field_name);
for (auto com_expr : leaf_query->range_query_ptr->compare_expr) {
auto grpc_com_expr = range_query->add_operand();
grpc_com_expr->set_operand(com_expr.operand);
grpc_com_expr->set_operator_((milvus::grpc::CompareOperator)com_expr.compare_operator);
}
}
if (leaf_query->vector_query_ptr != nullptr) {
auto vector_query = grpc_query->mutable_vector_query();
vector_query->set_field_name(leaf_query->vector_query_ptr->field_name);
vector_query->set_query_boost(leaf_query->query_boost);
vector_query->set_topk(leaf_query->vector_query_ptr->topk);
for (auto record : leaf_query->vector_query_ptr->query_vector) {
::milvus::grpc::RowRecord* row_record = vector_query->add_records();
CopyRowRecord(row_record, record);
}
auto extra_param = vector_query->add_extra_params();
extra_param->set_key(EXTRA_PARAM_KEY);
extra_param->set_value(leaf_query->vector_query_ptr->extra_params);
}
}
}
}
Status
ClientProxy::HybridSearch(const std::string& collection_name,
const std::vector<std::string>& partition_list,
BooleanQueryPtr& boolean_query,
const std::string& extra_params,
TopKQueryResult& topk_query_result) {
try {
// convert boolean_query to proto
::milvus::grpc::HSearchParam search_param;
search_param.set_collection_name(collection_name);
for (auto partition : partition_list) {
auto value = search_param.add_partition_tag_array();
*value = partition;
}
auto extra_param = search_param.add_extra_params();
extra_param->set_key("params");
extra_param->set_value(extra_params);
WriteQueryToProto(search_param.mutable_general_query(), boolean_query);
// step 2: search vectors
::milvus::grpc::TopKQueryResult result;
Status status = client_ptr_->HybridSearch(search_param, result);
// step 3: convert result array
topk_query_result.reserve(result.row_num());
int64_t nq = result.row_num();
if (nq == 0) {
return status;
}
int64_t topk = result.ids().size() / nq;
for (int64_t i = 0; i < result.row_num(); i++) {
milvus::QueryResult one_result;
one_result.ids.resize(topk);
one_result.distances.resize(topk);
memcpy(one_result.ids.data(), result.ids().data() + topk * i, topk * sizeof(int64_t));
memcpy(one_result.distances.data(), result.distances().data() + topk * i, topk * sizeof(float));
topk_query_result.emplace_back(one_result);
}
return status;
} catch (std::exception& ex) {
return Status(StatusCode::UnknownError, "Failed to search entities: " + std::string(ex.what()));
}
}
} // namespace milvus

View File

@ -122,6 +122,24 @@ class ClientProxy : public Connection {
Status
CompactCollection(const std::string& collection_name) override;
/*******************************New Interface**********************************/
Status
CreateHybridCollection(const HMapping& mapping) override;
Status
InsertEntity(const std::string& collection_name,
const std::string& partition_tag,
HEntity& entities,
std::vector<uint64_t>& id_array) override;
Status
HybridSearch(const std::string& collection_name,
const std::vector<std::string>& partition_list,
BooleanQueryPtr& boolean_query,
const std::string& extra_params,
TopKQueryResult& topk_query_result) override;
private:
std::shared_ptr<::grpc::Channel> channel_;
std::shared_ptr<GrpcClient> client_ptr_;

View File

@ -455,4 +455,56 @@ GrpcClient::Disconnect() {
return Status::OK();
}
Status
GrpcClient::CreateHybridCollection(milvus::grpc::Mapping& mapping) {
ClientContext context;
::milvus::grpc::Status response;
::grpc::Status grpc_status = stub_->CreateHybridCollection(&context, mapping, &response);
if (!grpc_status.ok()) {
std::cerr << "CreateHybridCollection gRPC failed!" << std::endl;
return Status(StatusCode::RPCFailed, grpc_status.error_message());
}
if (response.error_code() != grpc::SUCCESS) {
std::cerr << response.reason() << std::endl;
return Status(StatusCode::ServerFailed, response.reason());
}
return Status::OK();
}
Status
GrpcClient::InsertEntities(milvus::grpc::HInsertParam& entities, milvus::grpc::HEntityIDs& ids) {
ClientContext context;
::grpc::Status grpc_status = stub_->InsertEntity(&context, entities, &ids);
if (!grpc_status.ok()) {
std::cerr << "InsertEntities gRPC failed!" << std::endl;
return Status(StatusCode::RPCFailed, grpc_status.error_message());
}
if (ids.status().error_code() != grpc::SUCCESS) {
std::cerr << ids.status().reason() << std::endl;
return Status(StatusCode::ServerFailed, ids.status().reason());
}
return Status::OK();
}
Status
GrpcClient::HybridSearch(milvus::grpc::HSearchParam& search_param, milvus::grpc::TopKQueryResult& result) {
ClientContext context;
::grpc::Status grpc_status = stub_->HybridSearch(&context, search_param, &result);
if (!grpc_status.ok()) {
std::cerr << "HybridSearch gRPC failed!" << std::endl;
return Status(StatusCode::RPCFailed, grpc_status.error_message());
}
if (result.status().error_code() != grpc::SUCCESS) {
std::cerr << result.status().reason() << std::endl;
return Status(StatusCode::ServerFailed, result.status().reason());
}
return Status::OK();
}
} // namespace milvus

View File

@ -104,6 +104,16 @@ class GrpcClient {
Status
Disconnect();
/*******************************New Interface**********************************/
Status
CreateHybridCollection(milvus::grpc::Mapping& mapping);
Status
InsertEntities(milvus::grpc::HInsertParam& entities, milvus::grpc::HEntityIDs& ids);
Status
HybridSearch(milvus::grpc::HSearchParam& search_param, milvus::grpc::TopKQueryResult& result);
private:
std::unique_ptr<grpc::MilvusService::Stub> stub_;
};

View File

@ -0,0 +1,68 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <iostream>
#include <memory>
#include <vector>
#include <string>
# include "GeneralQuery.h"
namespace milvus {
enum class Occur {
INVALID = 0,
MUST,
MUST_NOT,
SHOULD,
};
class BooleanQuery {
public:
BooleanQuery() {}
BooleanQuery(Occur occur) : occur_(occur) {}
void
AddLeafQuery(LeafQueryPtr leaf_query) {
leaf_queries_.emplace_back(leaf_query);
}
void
AddBooleanQuery(std::shared_ptr<BooleanQuery> boolean_query) {
boolean_queries_.emplace_back(boolean_query);
}
std::vector<std::shared_ptr<BooleanQuery>>&
GetBooleanQueries() {
return boolean_queries_;
}
std::vector<LeafQueryPtr>&
GetLeafQueries() {
return leaf_queries_;
}
Occur
GetOccur() {
return occur_;
}
private:
Occur occur_;
std::vector<std::shared_ptr<BooleanQuery>> boolean_queries_;
std::vector<LeafQueryPtr> leaf_queries_;
};
using BooleanQueryPtr = std::shared_ptr<BooleanQuery>;
}

64
sdk/include/Field.h Normal file
View File

@ -0,0 +1,64 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "Status.h"
namespace milvus {
enum class DataType {
INT8 = 1,
INT16 = 2,
INT32 = 3,
INT64 = 4,
STRING = 20,
BOOL = 30,
FLOAT = 40,
DOUBLE = 41,
VECTOR = 100,
UNKNOWN = 9999,
};
// Base struct of all fields
struct Field {
uint64_t field_id; ///< read-only
std::string field_name;
DataType field_type;
float boost;
std::string extram_params;
};
using FieldPtr = std::shared_ptr<Field>;
// DistanceMetric
enum class DistanceMetric {
L2 = 1, // Euclidean Distance
IP = 2, // Cosine Similarity
HAMMING = 3, // Hamming Distance
JACCARD = 4, // Jaccard Distance
TANIMOTO = 5, // Tanimoto Distance
};
// vector field
struct VectorField : Field {
uint64_t dimension;
};
using VectorFieldPtr = std::shared_ptr<VectorField>;
}

View File

@ -0,0 +1,96 @@
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions and limitations under the License.
#pragma once
#include <iostream>
#include <memory>
#include <vector>
#include <string>
namespace milvus {
/**
* @brief Entity inserted, currently each entity represent a vector
*/
struct Entity {
std::vector<float> float_data; ///< Vector raw float data
std::vector<uint8_t> binary_data; ///< Vector raw binary data
};
// base class of all queries
struct Sort {
std::string field_name;
int64_t rules; // 0 is inc, 1 is dec
};
struct Query {
std::string field_name;
int64_t from;
int64_t size;
Sort sort;
float min_score;
float boost;
};
enum class CompareOperator {
LT = 0,
LTE,
EQ,
GT,
GTE,
NE,
};
struct QueryColumn {
std::string name;
std::string column_value;
};
struct TermQuery : Query {
std::vector<std::string> field_value;
};
using TermQueryPtr = std::shared_ptr<TermQuery>;
struct CompareExpr {
CompareOperator compare_operator;
std::string operand;
};
struct RangeQuery : Query {
std::vector<CompareExpr> compare_expr;
};
using RangeQueryPtr = std::shared_ptr<RangeQuery>;
struct RowRecord {
std::vector<float> float_data;
std::vector<uint8_t> binary_data;
};
struct VectorQuery : Query {
uint64_t topk;
float distance_limitation;
float query_boost;
std::vector<Entity> query_vector;
std::string extra_params;
};
using VectorQueryPtr = std::shared_ptr<VectorQuery>;
struct LeafQuery {
TermQueryPtr term_query_ptr;
RangeQueryPtr range_query_ptr;
VectorQueryPtr vector_query_ptr;
float query_boost;
};
using LeafQueryPtr = std::shared_ptr<LeafQuery>;
}

View File

@ -14,7 +14,10 @@
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include "BooleanQuery.h"
#include "Field.h"
#include "Status.h"
/** \brief Milvus SDK namespace
@ -66,14 +69,6 @@ struct CollectionParam {
MetricType metric_type = MetricType::L2; ///< Index metric type
};
/**
* @brief Entity inserted, currently each entity represent a vector
*/
struct Entity {
std::vector<float> float_data; ///< Vector raw float data
std::vector<uint8_t> binary_data; ///< Vector raw binary data
};
/**
* @brief TopK query result
*/
@ -144,6 +139,22 @@ struct CollectionInfo {
std::vector<PartitionStat> partitions_stat; ///< Collection's partitions statistics
};
struct HMapping {
std::string collection_name;
std::vector<FieldPtr> numerica_fields;
std::vector<VectorFieldPtr> vector_fields;
};
struct HEntity {
std::unordered_map<std::string, std::vector<std::string>> numerica_value;
std::unordered_map<std::string, std::vector<Entity>> vector_value;
};
/**
* @brief SDK main class
*/
@ -575,6 +586,24 @@ class Connection {
*/
virtual Status
CompactCollection(const std::string& collection_name) = 0;
/*******************************New Interface**********************************/
virtual Status
CreateHybridCollection(const HMapping& mapping) = 0;
virtual Status
InsertEntity(const std::string& collection_name,
const std::string& partition_tag,
HEntity& entities,
std::vector<uint64_t>& id_array) = 0;
virtual Status
HybridSearch(const std::string& collection_name,
const std::vector<std::string>& partition_list,
BooleanQueryPtr& boolean_query,
const std::string& extra_params,
TopKQueryResult& topk_query_result) = 0;
};
} // namespace milvus

View File

@ -190,4 +190,28 @@ ConnectionImpl::CompactCollection(const std::string& collection_name) {
return client_proxy_->CompactCollection(collection_name);
}
/*******************************New Interface**********************************/
Status
ConnectionImpl::CreateHybridCollection(const HMapping& mapping) {
return client_proxy_->CreateHybridCollection(mapping);
}
Status
ConnectionImpl::InsertEntity(const std::string& collection_name,
const std::string& partition_tag,
HEntity& entities,
std::vector<uint64_t>& id_array) {
return client_proxy_->InsertEntity(collection_name, partition_tag, entities, id_array);
}
Status
ConnectionImpl::HybridSearch(const std::string& collection_name,
const std::vector<std::string>& partition_list,
BooleanQueryPtr& boolean_query,
const std::string& extra_params,
TopKQueryResult& topk_query_result) {
return client_proxy_->HybridSearch(collection_name, partition_list, boolean_query, extra_params, topk_query_result);
}
} // namespace milvus

View File

@ -124,6 +124,24 @@ class ConnectionImpl : public Connection {
Status
CompactCollection(const std::string& collection_name) override;
/*******************************New Interface**********************************/
Status
CreateHybridCollection(const HMapping& mapping) override ;
Status
InsertEntity(const std::string& collection_name,
const std::string& partition_tag,
HEntity& entities,
std::vector<uint64_t>& id_array) override ;
Status
HybridSearch(const std::string& collection_name,
const std::vector<std::string>& partition_list,
BooleanQueryPtr& boolean_query,
const std::string& extra_params,
TopKQueryResult& topk_query_result) override;
private:
std::shared_ptr<ClientProxy> client_proxy_;
};