| 941 | } |
| 942 | |
| 943 | DatasetPtr |
| 944 | IVF::SearchWithRequest(const SearchRequest& request) const { |
| 945 | SearchStatistics stats; |
| 946 | QueryContext ctx{.alloc = request.search_allocator_, .stats = &stats}; |
| 947 | |
| 948 | auto param = this->create_search_param(request.params_str_, request.filter_); |
| 949 | param.search_mode = KNN_SEARCH; |
| 950 | param.topk = request.topk_; |
| 951 | if (use_reorder_) { |
| 952 | CHECK_ARGUMENT( |
| 953 | param.factor > 0.0F, |
| 954 | fmt::format("factor must be positive when use_reorder is true, got {}", param.factor)); |
| 955 | param.topk = static_cast<int64_t>(param.factor * static_cast<float>(request.topk_)); |
| 956 | } |
| 957 | auto query = request.query_; |
| 958 | if (request.enable_attribute_filter_ and this->attr_filter_index_ != nullptr) { |
| 959 | auto& schema = this->attr_filter_index_->field_type_map_; |
| 960 | auto expr = AstParse(request.attribute_filter_str_, &schema); |
| 961 | for (int64_t i = 0; i < param.parallel_search_thread_count; ++i) { |
| 962 | auto executor = |
| 963 | Executor::MakeInstance(this->allocator_, expr, this->attr_filter_index_); |
| 964 | executor->Init(); |
| 965 | param.executors.emplace_back(executor); |
| 966 | } |
| 967 | } |
| 968 | auto search_result = this->search<KNN_SEARCH>(query, param, ctx); |
| 969 | if (use_reorder_) { |
| 970 | return reorder(request.topk_, search_result, query->GetFloat32Vectors(), param, ctx); |
| 971 | } |
| 972 | auto count = static_cast<const int64_t>(search_result->Size()); |
| 973 | auto [dataset_results, dists, labels] = create_fast_dataset(count, allocator_); |
| 974 | for (int64_t j = count - 1; j >= 0; --j) { |
| 975 | dists[j] = search_result->Top().first; |
| 976 | labels[j] = label_table_->GetLabelById(search_result->Top().second); |
| 977 | search_result->Pop(); |
| 978 | } |
| 979 | |
| 980 | dataset_results->Statistics(stats.Dump()); |
| 981 | return std::move(dataset_results); |
| 982 | } |
| 983 | |
| 984 | void |
| 985 | IVF::fill_location_map() { |