Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion be/src/vec/functions/function_search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,8 @@ Status FunctionSearch::evaluate_inverted_index_with_search_param(
// Aligned with FE QsClauseType enum - uses enum.name() as clause_type
FunctionSearch::ClauseTypeCategory FunctionSearch::get_clause_type_category(
const std::string& clause_type) const {
if (clause_type == "AND" || clause_type == "OR" || clause_type == "NOT") {
if (clause_type == "AND" || clause_type == "OR" || clause_type == "NOT" ||
clause_type == "OCCUR_BOOLEAN") {
return ClauseTypeCategory::COMPOUND;
} else if (clause_type == "TERM" || clause_type == "PREFIX" || clause_type == "WILDCARD" ||
clause_type == "REGEXP" || clause_type == "RANGE" || clause_type == "LIST" ||
Expand Down Expand Up @@ -377,6 +378,7 @@ InvertedIndexQueryType FunctionSearch::clause_type_to_query_type(
{"AND", InvertedIndexQueryType::BOOLEAN_QUERY},
{"OR", InvertedIndexQueryType::BOOLEAN_QUERY},
{"NOT", InvertedIndexQueryType::BOOLEAN_QUERY},
{"OCCUR_BOOLEAN", InvertedIndexQueryType::BOOLEAN_QUERY},

// Non-tokenized queries (exact matching, pattern matching)
{"TERM", InvertedIndexQueryType::EQUAL_QUERY},
Expand Down Expand Up @@ -406,6 +408,20 @@ InvertedIndexQueryType FunctionSearch::clause_type_to_query_type(
return InvertedIndexQueryType::EQUAL_QUERY;
}

// Map Thrift TSearchOccur to query_v2::Occur
static query_v2::Occur map_thrift_occur(TSearchOccur::type thrift_occur) {
switch (thrift_occur) {
case TSearchOccur::MUST:
return query_v2::Occur::MUST;
case TSearchOccur::SHOULD:
return query_v2::Occur::SHOULD;
case TSearchOccur::MUST_NOT:
return query_v2::Occur::MUST_NOT;
default:
return query_v2::Occur::MUST;
}
}

Status FunctionSearch::build_query_recursive(const TSearchClause& clause,
const std::shared_ptr<IndexQueryContext>& context,
FieldReaderResolver& resolver,
Expand All @@ -418,6 +434,38 @@ Status FunctionSearch::build_query_recursive(const TSearchClause& clause,
}

const std::string& clause_type = clause.clause_type;

// Handle OCCUR_BOOLEAN - Lucene-style boolean query with MUST/SHOULD/MUST_NOT
if (clause_type == "OCCUR_BOOLEAN") {
auto builder = segment_v2::inverted_index::query_v2::create_occur_boolean_query_builder();

// Set minimum_should_match if specified
if (clause.__isset.minimum_should_match) {
builder->set_minimum_number_should_match(clause.minimum_should_match);
}

if (clause.__isset.children) {
for (const auto& child_clause : clause.children) {
query_v2::QueryPtr child_query;
std::string child_binding_key;
RETURN_IF_ERROR(build_query_recursive(child_clause, context, resolver, &child_query,
&child_binding_key));

// Determine occur type from child clause
query_v2::Occur occur = query_v2::Occur::MUST; // default
if (child_clause.__isset.occur) {
occur = map_thrift_occur(child_clause.occur);
}

builder->add(child_query, occur);
}
}

*out = builder->build();
return Status::OK();
}

// Handle standard boolean operators (AND/OR/NOT)
if (clause_type == "AND" || clause_type == "OR" || clause_type == "NOT") {
query_v2::OperatorType op = query_v2::OperatorType::OP_AND;
if (clause_type == "OR") {
Expand Down
Loading
Loading