mirror of
https://gitee.com/milvus-io/milvus.git
synced 2026-01-04 18:02:08 +08:00
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:
parent
6a36eaa982
commit
3e1b2ab4a0
@ -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}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -33,6 +33,9 @@ class Codec {
|
||||
virtual VectorsFormatPtr
|
||||
GetVectorsFormat() = 0;
|
||||
|
||||
virtual AttrsFormatPtr
|
||||
GetAttrsFormat() = 0;
|
||||
|
||||
virtual VectorIndexFormatPtr
|
||||
GetVectorIndexFormat() = 0;
|
||||
|
||||
|
||||
247
core/src/codecs/default/DefaultAttrsFormat.cpp
Normal file
247
core/src/codecs/default/DefaultAttrsFormat.cpp
Normal 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
|
||||
67
core/src/codecs/default/DefaultAttrsFormat.h
Normal file
67
core/src/codecs/default/DefaultAttrsFormat.h
Normal 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
|
||||
@ -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_;
|
||||
|
||||
@ -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_;
|
||||
|
||||
39
core/src/context/HybridSearchContext.h
Normal file
39
core/src/context/HybridSearchContext.h
Normal 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
|
||||
@ -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>;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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>;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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_;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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_);
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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>;
|
||||
|
||||
@ -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>;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
@ -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) {}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
}
|
||||
222
core/src/query/BinaryQuery.cpp
Normal file
222
core/src/query/BinaryQuery.cpp
Normal 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
|
||||
38
core/src/query/BinaryQuery.h
Normal file
38
core/src/query/BinaryQuery.h
Normal 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
|
||||
87
core/src/query/BooleanQuery.h
Normal file
87
core/src/query/BooleanQuery.h
Normal 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
|
||||
107
core/src/query/GeneralQuery.h
Normal file
107
core/src/query/GeneralQuery.h
Normal 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
|
||||
@ -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_);
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
|
||||
@ -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
223
core/src/search/Task.cpp
Normal 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
93
core/src/search/Task.h
Normal 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
|
||||
116
core/src/search/TaskInst.cpp
Normal file
116
core/src/search/TaskInst.cpp
Normal 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
|
||||
82
core/src/search/TaskInst.h
Normal file
82
core/src/search/TaskInst.h
Normal 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
168
core/src/segment/Attr.cpp
Normal 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
|
||||
@ -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>;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
134
core/src/server/delivery/hybrid_request/HybridSearchRequest.cpp
Normal file
134
core/src/server/delivery/hybrid_request/HybridSearchRequest.cpp
Normal 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
|
||||
@ -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
|
||||
205
core/src/server/delivery/hybrid_request/InsertEntityRequest.cpp
Normal file
205
core/src/server/delivery/hybrid_request/InsertEntityRequest.cpp
Normal 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
|
||||
@ -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
|
||||
@ -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);
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
283
core/unittest/db/test_hybrid_db.cpp
Normal file
283
core/unittest/db/test_hybrid_db.cpp
Normal 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());
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
@ -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
|
||||
|
||||
@ -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_;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
|
||||
68
sdk/include/BooleanQuery.h
Normal file
68
sdk/include/BooleanQuery.h
Normal 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
64
sdk/include/Field.h
Normal 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>;
|
||||
|
||||
}
|
||||
96
sdk/include/GeneralQuery.h
Normal file
96
sdk/include/GeneralQuery.h
Normal 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>;
|
||||
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user