blob: a5b5bd06d90ce72ebfc748771bd05201bd52d4be [file]
// 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 "storage/index/inverted/query/query_helper.h"
namespace doris::segment_v2 {
void QueryHelper::collect(const IndexQueryContextPtr& context,
const std::vector<SimilarityPtr>& similarities,
const std::vector<TermIterPtr>& iterators, int32_t doc) {
for (size_t i = 0; i < iterators.size(); i++) {
auto freq = iterators[i]->freq();
auto doc_length = iterators[i]->norm();
auto score = similarities[i]->score(static_cast<float>(freq), doc_length);
context->collection_similarity->collect(doc, score);
}
}
void QueryHelper::collect(const IndexQueryContextPtr& context,
const std::vector<SimilarityPtr>& similarities,
const std::vector<DISI>& iterators, int32_t doc) {
for (size_t i = 0; i < iterators.size(); i++) {
const auto& iter = iterators[i];
if (std::holds_alternative<TermPositionsIterPtr>(iter)) {
const auto& term_iter = std::get<TermPositionsIterPtr>(iter);
auto freq = term_iter->freq();
auto norm = term_iter->norm();
auto score = similarities[i]->score(static_cast<float>(freq), norm);
context->collection_similarity->collect(doc, score);
}
}
}
void QueryHelper::collect_many(const IndexQueryContextPtr& context, const SimilarityPtr& similarity,
const DocRange& doc_range) {
for (size_t j = 0; j < doc_range.doc_many_size_; j++) {
rowid_t row_id = (*doc_range.doc_many)[j];
auto freq = (*doc_range.freq_many)[j];
auto norm = (*doc_range.norm_many)[j];
auto score = similarity->score(static_cast<float>(freq), norm);
context->collection_similarity->collect(row_id, score);
}
}
void QueryHelper::collect_range(const IndexQueryContextPtr& context,
const SimilarityPtr& similarity, const DocRange& doc_range) {
const uint32_t docs_size = doc_range.doc_range.second - doc_range.doc_range.first;
for (uint32_t j = 0; j < docs_size; j++) {
segment_v2::rowid_t row_id = doc_range.doc_range.first + j;
auto freq = (*doc_range.freq_many)[j];
auto norm = (*doc_range.norm_many)[j];
auto score = similarity->score(static_cast<float>(freq), norm);
context->collection_similarity->collect(row_id, score);
}
}
bool QueryHelper::is_simple_phrase(const std::vector<TermInfo>& term_infos) {
return std::ranges::all_of(term_infos,
[](const auto& term_info) { return term_info.is_single_term(); });
}
std::vector<TermInfo> QueryHelper::build_phrase_term_infos(const std::vector<TermInfo>& src) {
std::vector<TermInfo> dst;
dst.reserve(src.size());
size_t idx = 0;
while (idx < src.size()) {
int32_t pos = src[idx].position;
std::vector<std::string> group_terms;
while (idx < src.size() && src[idx].position == pos) {
const auto& info = src[idx];
if (info.is_single_term()) {
group_terms.emplace_back(info.get_single_term());
} else {
const auto& terms = info.get_multi_terms();
group_terms.insert(group_terms.end(), terms.begin(), terms.end());
}
++idx;
}
TermInfo t;
t.position = pos;
if (group_terms.size() == 1) {
t.term = std::move(group_terms[0]);
} else {
t.term = std::move(group_terms);
}
dst.emplace_back(std::move(t));
}
return dst;
}
} // namespace doris::segment_v2