This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 4735ebc17fb branch-4.1: [fix](be) Score regexp and wildcard patterns 
with a constant like Elasticsearch (#69825)
4735ebc17fb is described below

commit 4735ebc17fbbcdcc02abbbadb74550acf93640ea
Author: Jack <[email protected]>
AuthorDate: Fri Oct 30 18:29:46 2026 +0800

    branch-4.1: [fix](be) Score regexp and wildcard patterns with a constant 
like Elasticsearch (#69825)
    
    ### What problem does this PR solve?
    
    Issue Number: None
    
    Related PR: #69815, #69269
    
    Problem Summary: score() of pattern queries disagrees with Elasticsearch
    and with itself on branch-4.1:
    
        -- 'Inverted indexes are suitable for full text search',
        -- 'The parser splits text into multiple terms', ...
    SELECT score() FROM document WHERE SEARCH('content:/.*ext/'); -- BM25
    sum
    SELECT score() FROM document WHERE SEARCH('content:*ext'); -- BM25 sum
        SELECT score() FROM document WHERE content MATCH_REGEXP 'ext'; -- 0
    
    Elasticsearch scores a query_string /regexp/, wildcard or prefix, and a
    regexp, wildcard or prefix query, with a constant 1 per matching row
    (default rewrite constant_score_blended); measured on 9.5.5 with the
    rows above: 1.0 for both matching rows. Only an explicit
    "rewrite": "scoring_boolean" sums the BM25 of the expanded terms. Next
    to a scored clause in a bool must, a regexp adds exactly 1.
    
    #69269 (the branch-4.1 pick of #69052) made SEARCH regexp and wildcard
    sum the BM25 of every expanded term, i.e. scoring_boolean always on,
    with idf and avgdl taken from the current segment rather than the tablet
    statistics MATCH uses, so identical rows in two segments scored
    differently. MATCH_REGEXP never requested a scoring context, so it
    scored 0 like a filter.
    
    Fix, the same as #69815 on master:
    1. Revert #69269: RegexpWeight scores every pattern with the constant
       scorer again; its suite that pinned the BM25 sums is removed.
    2. MATCH_REGEXP requests scoring on every index, and the legacy
       RegexpQuery records 1 for every matching row when score() is
       requested. The MATCH statistics collector skips it, since a constant
       reads no statistics and the pattern is not text to analyze.
    
    A MATCH_REGEXP on a keyword (untokenized) index also scores 1 once the
    keyword reader requests scoring (#69791); until then it keeps 0.
    
    ### Release note
    
    score() of SEARCH regexp and wildcard clauses is a constant 1 per
    matching row again, like prefix clauses and Elasticsearch's default.
    score() of MATCH_REGEXP on a tokenized index is 1 instead of 0.
    
    ### Check List (For Author)
    
    - Test: Regression test / Unit Test / Manual test
        - Regression test: new search/test_search_score_pattern_constant
          (V2/V3, two segments); all 18 blocks equal the master PR's V2/V3
          blocks; 16 existing score suites in inverted_index_p0 and search
          pass unchanged
    - Unit Test: 130 tests (IndexReaderHelperTest, CollectionStatistics*,
          RegexpQueryTest and the query_v2 regexp/wildcard tests restored by
          the revert)
        - Manual test: Elasticsearch 9.5.5 on the same rows; a two-segment
    table now scores 1 for every pattern hit on a branch-4.1 ASAN build
    - Behavior changed: Yes. SEARCH regexp/wildcard scores and MATCH_REGEXP
      scores change as described in the release note.
    - Does this need documentation: No
    
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-authored-by: Claude Opus 5.5 <[email protected]>
---
 be/src/storage/index/index_reader_helper.h         |  10 +
 .../storage/index/inverted/query/regexp_query.cpp  |   9 +
 be/src/storage/index/inverted/query/regexp_query.h |   2 +
 .../query_v2/regexp_query/regexp_weight.cpp        |  50 ---
 .../inverted/query_v2/regexp_query/regexp_weight.h |   6 +-
 be/src/storage/predicate_collector.cpp             |   5 +
 .../compaction/collection_statistics_test.cpp      |  46 +++
 .../index/inverted/query/regexp_query_test.cpp     |  34 +++
 .../index/inverted/query_v2/regexp_query_test.cpp  |  61 +---
 .../inverted/query_v2/wildcard_query_test.cpp      |  72 +----
 .../storage/segment/index_reader_helper_test.cpp   |  26 ++
 .../search/test_search_score_pattern_constant.out  |  75 +++++
 .../search/test_search_score_regexp_wildcard.out   | 337 ---------------------
 .../test_search_score_pattern_constant.groovy      |  79 +++++
 .../test_search_score_regexp_wildcard.groovy       |  80 -----
 15 files changed, 301 insertions(+), 591 deletions(-)

diff --git a/be/src/storage/index/index_reader_helper.h 
b/be/src/storage/index/index_reader_helper.h
index 988db5c73ec..4b436feed5f 100644
--- a/be/src/storage/index/index_reader_helper.h
+++ b/be/src/storage/index/index_reader_helper.h
@@ -106,6 +106,12 @@ public:
 
     static bool is_need_similarity_score(InvertedIndexQueryType query_type,
                                          const TabletIndex* index_meta) {
+        // A regexp scores a constant 1 per matching row, as an Elasticsearch 
regexp query does in
+        // query context. The constant reads no statistics, norms or 
positions, so every index can
+        // score it.
+        if (query_type == InvertedIndexQueryType::MATCH_REGEXP_QUERY) {
+            return true;
+        }
         if (query_type == InvertedIndexQueryType::MATCH_ANY_QUERY ||
             query_type == InvertedIndexQueryType::MATCH_ALL_QUERY ||
             query_type == InvertedIndexQueryType::MATCH_PHRASE_QUERY ||
@@ -122,6 +128,10 @@ public:
 
     static bool is_need_similarity_score(TExprOpcode::type query_type,
                                          const TabletIndex* index_meta) {
+        // See the InvertedIndexQueryType overload: a regexp scores a constant 
on every index.
+        if (query_type == TExprOpcode::MATCH_REGEXP) {
+            return true;
+        }
         if (query_type == TExprOpcode::MATCH_ANY || query_type == 
TExprOpcode::MATCH_ALL ||
             query_type == TExprOpcode::MATCH_PHRASE ||
             query_type == TExprOpcode::MATCH_PHRASE_PREFIX) {
diff --git a/be/src/storage/index/inverted/query/regexp_query.cpp 
b/be/src/storage/index/inverted/query/regexp_query.cpp
index bb35a9275a2..f12b93a177f 100644
--- a/be/src/storage/index/inverted/query/regexp_query.cpp
+++ b/be/src/storage/index/inverted/query/regexp_query.cpp
@@ -39,6 +39,7 @@ void RegexpQuery::add(const InvertedIndexQueryInfo& 
query_info) {
     if (query_info.term_infos.empty()) {
         throw Exception(ErrorCode::INVALID_ARGUMENT, "term_infos cannot be 
empty");
     }
+    _constant_score = _context->collection_similarity && 
query_info.is_similarity_score;
 
     const std::string& pattern = query_info.term_infos[0].get_single_term();
     if (is_hyperscan_regexp_expensive(pattern)) {
@@ -84,6 +85,14 @@ void RegexpQuery::add(const InvertedIndexQueryInfo& 
query_info) {
 
 void RegexpQuery::search(roaring::Roaring& roaring) {
     _query.search(roaring);
+    // A regexp scores a constant 1 per matching row, as an Elasticsearch 
regexp query does in query
+    // context, so body MATCH 'apple' AND body MATCH_REGEXP 'ap.*' adds 1 to 
the apple score. The
+    // expanded terms' own BM25 would depend on how many terms the pattern 
happens to match.
+    if (_constant_score) {
+        for (const auto row_id : roaring) {
+            _context->collection_similarity->collect(row_id, 1.0F);
+        }
+    }
 }
 
 std::optional<std::string> RegexpQuery::get_regex_prefix(const std::string& 
pattern) {
diff --git a/be/src/storage/index/inverted/query/regexp_query.h 
b/be/src/storage/index/inverted/query/regexp_query.h
index c0d56ffbeae..55a37299dbe 100644
--- a/be/src/storage/index/inverted/query/regexp_query.h
+++ b/be/src/storage/index/inverted/query/regexp_query.h
@@ -50,6 +50,8 @@ private:
 
     int32_t _max_expansions = 50;
     DisjunctionQuery _query;
+    // Set when score() is requested; every matching row then scores the 
constant 1.
+    bool _constant_score = false;
 
     friend class RegexpQueryTest;
 };
diff --git 
a/be/src/storage/index/inverted/query_v2/regexp_query/regexp_weight.cpp 
b/be/src/storage/index/inverted/query_v2/regexp_query/regexp_weight.cpp
index e2576724ab4..5ecfad0d3ae 100644
--- a/be/src/storage/index/inverted/query_v2/regexp_query/regexp_weight.cpp
+++ b/be/src/storage/index/inverted/query_v2/regexp_query/regexp_weight.cpp
@@ -34,18 +34,12 @@
 #include <gen_cpp/PaloBrokerService_types.h>
 
 #include <algorithm>
-#include <cmath>
 #include <string>
-#include <vector>
 
 #include "storage/index/inverted/query_v2/bit_set_query/bit_set_scorer.h"
 #include 
"storage/index/inverted/query_v2/const_score_query/const_score_scorer.h"
 #include "storage/index/inverted/query_v2/nullable_scorer.h"
-#include "storage/index/inverted/query_v2/score_combiner.h"
 #include "storage/index/inverted/query_v2/segment_postings.h"
-#include "storage/index/inverted/query_v2/term_query/term_scorer.h"
-#include "storage/index/inverted/query_v2/union/buffered_union.h"
-#include "storage/index/inverted/similarity/bm25_similarity.h"
 #include "storage/index/inverted/util/string_helper.h"
 #include "util/hyperscan_util.h"
 
@@ -116,10 +110,6 @@ ScorerPtr RegexpWeight::regexp_scorer(const 
QueryExecutionContext& context,
     }
 
     auto reader = lookup_reader(_field, context, binding_key);
-    if (_enable_scoring) {
-        return scored_terms_scorer(reader.get(), context, binding_key, 
matching_terms);
-    }
-
     auto doc_bitset = std::make_shared<roaring::Roaring>();
     for (const auto& term : matching_terms) {
         auto segment_postings =
@@ -136,46 +126,6 @@ ScorerPtr RegexpWeight::regexp_scorer(const 
QueryExecutionContext& context,
     return const_score;
 }
 
-ScorerPtr RegexpWeight::scored_terms_scorer(lucene::index::IndexReader* reader,
-                                            const QueryExecutionContext& 
context,
-                                            const std::string& binding_key,
-                                            const std::vector<std::wstring>& 
matching_terms) {
-    // Expanded terms are not collected in collection statistics, so use 
reader statistics.
-    const auto num_docs = reader->maxDoc();
-    DORIS_CHECK_GT(num_docs, 0);
-    const auto total_term_freq = reader->sumTotalTermFreq(_field.c_str());
-    // Without norms, postings use a document length of one.
-    const float avgdl = static_cast<float>(total_term_freq.value_or(num_docs)) 
/ num_docs;
-    DORIS_CHECK_GT(avgdl, 0.0F);
-
-    std::vector<ScorerPtr> term_scorers;
-    term_scorers.reserve(matching_terms.size());
-    auto logical_field = logical_field_or_fallback(context, binding_key, 
_field);
-    for (const auto& term : matching_terms) {
-        Term lucene_term(_field.c_str(), term.c_str());
-        const int32_t doc_freq = reader->docFreq(&lucene_term);
-        if (doc_freq == 0) {
-            continue;
-        }
-        const auto idf = static_cast<float>(
-                std::log1p((static_cast<double>(num_docs) - doc_freq + 0.5) / 
(doc_freq + 0.5)));
-        auto similarity = std::make_shared<BM25Similarity>(idf, avgdl);
-        auto posting =
-                create_term_posting(reader, _field, term, true, similarity, 
_context->io_ctx);
-        if (posting) {
-            term_scorers.emplace_back(std::make_shared<TermScorer>(
-                    std::move(posting), std::move(similarity), logical_field));
-        }
-    }
-    if (term_scorers.empty()) {
-        return std::make_shared<EmptyScorer>();
-    }
-    if (term_scorers.size() == 1) {
-        return std::move(term_scorers.front());
-    }
-    return make_buffered_union(term_scorers, std::make_shared<SumCombiner>());
-}
-
 std::optional<std::string> RegexpWeight::get_regex_prefix(const std::string& 
pattern) {
     DBUG_EXECUTE_IF("RegexpQuery.get_regex_prefix", { return std::nullopt; });
 
diff --git 
a/be/src/storage/index/inverted/query_v2/regexp_query/regexp_weight.h 
b/be/src/storage/index/inverted/query_v2/regexp_query/regexp_weight.h
index 6ef13c71fa5..f8b1a0ba9fa 100644
--- a/be/src/storage/index/inverted/query_v2/regexp_query/regexp_weight.h
+++ b/be/src/storage/index/inverted/query_v2/regexp_query/regexp_weight.h
@@ -35,10 +35,6 @@ public:
 
 private:
     ScorerPtr regexp_scorer(const QueryExecutionContext& context, const 
std::string& binding_key);
-    ScorerPtr scored_terms_scorer(lucene::index::IndexReader* reader,
-                                  const QueryExecutionContext& context,
-                                  const std::string& binding_key,
-                                  const std::vector<std::wstring>& 
matching_terms);
 
     std::optional<std::string> get_regex_prefix(const std::string& pattern);
     void collect_matching_terms(const QueryExecutionContext& context,
@@ -50,7 +46,7 @@ private:
 
     std::wstring _field;
     std::string _pattern;
-    bool _enable_scoring = false;
+    [[maybe_unused]] bool _enable_scoring = false;
     bool _nullable = true;
     // Set to 0 to disable limit (ES has no default limit for prefix queries)
     // The limit prevents collecting too many terms, but can cause incorrect 
results
diff --git a/be/src/storage/predicate_collector.cpp 
b/be/src/storage/predicate_collector.cpp
index b79ab47652e..cfebb513f50 100644
--- a/be/src/storage/predicate_collector.cpp
+++ b/be/src/storage/predicate_collector.cpp
@@ -295,6 +295,11 @@ Status MatchPredicateCollector::collect(RuntimeState* 
state, const TabletSchemaS
         if (!IndexReaderHelper::is_need_similarity_score(expr->op(), 
index_meta)) {
             continue;
         }
+        // A regexp scores a constant and reads no statistics. Its value is a 
pattern, not text, so
+        // analyzing it would collect statistics for made-up terms: 'ap.*' 
would become "ap".
+        if (expr->op() == TExprOpcode::MATCH_REGEXP) {
+            continue;
+        }
 
         auto options = DataTypeSerDe::get_default_format_options();
         options.timezone = &state->timezone_obj();
diff --git a/be/test/storage/compaction/collection_statistics_test.cpp 
b/be/test/storage/compaction/collection_statistics_test.cpp
index 7fa78f1e6a6..705e2bb3b21 100644
--- a/be/test/storage/compaction/collection_statistics_test.cpp
+++ b/be/test/storage/compaction/collection_statistics_test.cpp
@@ -1809,6 +1809,52 @@ TEST_F(CollectionStatisticsTest, 
CollectSkipsIndexWithoutAnalyzer) {
 // L2: Index whose analyzer is set (should_analyzer returns true) but does
 // not declare "support_phrase=true". MockVExpr drives MATCH_PHRASE opcode,
 // so is_need_similarity_score returns false and the index is skipped.
+// A regexp scores a constant, so it collects no statistics even on an index 
whose MATCH_ANY does:
+// analyzing its pattern 'ap.*' would register the made-up term "ap".
+TEST_F(CollectionStatisticsTest, RegexpCollectsNoStatistics) {
+    auto tablet_schema = std::make_shared<TabletSchema>();
+
+    constexpr int32_t kColUid = 1360;
+    TabletColumn col;
+    col.set_unique_id(kColUid);
+    col.set_name("body");
+    col.set_type(FieldType::OLAP_FIELD_TYPE_STRING);
+    tablet_schema->append_column(col);
+
+    TabletIndexPB index_pb;
+    index_pb.set_index_id(2360);
+    index_pb.set_index_name("body_idx");
+    index_pb.set_index_type(IndexType::INVERTED);
+    index_pb.add_col_unique_id(kColUid);
+    (*index_pb.mutable_properties())["parser"] = "english";
+    (*index_pb.mutable_properties())["support_phrase"] = "true";
+    TabletIndex index;
+    index.init_from_pb(index_pb);
+    tablet_schema->append_index(std::move(index));
+
+    constexpr int kSlotId = 86;
+    runtime_state_->_mock_desc_tbl->add_slot_descriptor(SlotId(kSlotId), 
kColUid, "body", {});
+
+    auto match_expr = 
std::make_shared<collection_statistics::MockVExpr>(TExprNodeType::MATCH_PRED);
+    match_expr->_children.push_back(
+            std::make_shared<collection_statistics::MockVSlotRef>("body", 
SlotId(kSlotId)));
+    
match_expr->_children.push_back(std::make_shared<collection_statistics::MockVLiteral>("ap.*"));
+
+    MatchPredicateCollector collector;
+    std::unordered_map<std::wstring, CollectInfo> collect_infos;
+    match_expr->_opcode = TExprOpcode::MATCH_ANY;
+    auto status =
+            collector.collect(runtime_state_.get(), tablet_schema, match_expr, 
&collect_infos);
+    ASSERT_TRUE(status.ok()) << status.msg();
+    EXPECT_EQ(collect_infos.size(), 1U);
+
+    collect_infos.clear();
+    match_expr->_opcode = TExprOpcode::MATCH_REGEXP;
+    status = collector.collect(runtime_state_.get(), tablet_schema, 
match_expr, &collect_infos);
+    ASSERT_TRUE(status.ok()) << status.msg();
+    EXPECT_TRUE(collect_infos.empty());
+}
+
 TEST_F(CollectionStatisticsTest, CollectSkipsIndexWithoutSimilarityScore) {
     auto tablet_schema = std::make_shared<TabletSchema>();
 
diff --git a/be/test/storage/index/inverted/query/regexp_query_test.cpp 
b/be/test/storage/index/inverted/query/regexp_query_test.cpp
index 40287b9dff1..a53e7672be2 100644
--- a/be/test/storage/index/inverted/query/regexp_query_test.cpp
+++ b/be/test/storage/index/inverted/query/regexp_query_test.cpp
@@ -25,6 +25,7 @@
 
 #include "io/fs/local_file_system.h"
 #include "runtime/runtime_state.h"
+#include "storage/compaction/collection_similarity.h"
 #include "storage/index/inverted/query/query.h"
 #include "storage/index/inverted/query/query_info.h"
 
@@ -298,6 +299,39 @@ TEST_F(RegexpQueryTest, SearchWithEmptyTerms) {
     EXPECT_TRUE(result.isEmpty());
 }
 
+// With score() a regexp scores the constant 1 for every matching row, and 
without it publishes
+// no score. The matching rows stand in for what the expanded terms' postings 
would return.
+TEST_F(RegexpQueryTest, ScoresConstantOnePerMatchingRow) {
+    std::shared_ptr<lucene::search::IndexSearcher> searcher = nullptr;
+    OlapReaderStatistics stats;
+    RuntimeState runtime_state;
+    io::IOContext io_ctx;
+    for (const bool constant_score : {false, true}) {
+        SCOPED_TRACE(constant_score);
+        auto context = std::make_shared<IndexQueryContext>();
+        context->runtime_state = &runtime_state;
+        context->stats = &stats;
+        context->io_ctx = &io_ctx;
+        context->collection_similarity = 
std::make_shared<CollectionSimilarity>();
+        RegexpQuery regexp_query(searcher, context);
+        regexp_query._constant_score = constant_score;
+
+        roaring::Roaring result;
+        result.add(1);
+        result.add(5);
+        regexp_query.search(result);
+
+        auto scores = context->collection_similarity->release_scores();
+        if (constant_score) {
+            ASSERT_EQ(scores.size(), 2U);
+            EXPECT_FLOAT_EQ(scores[1], 1.0F);
+            EXPECT_FLOAT_EQ(scores[5], 1.0F);
+        } else {
+            EXPECT_TRUE(scores.empty());
+        }
+    }
+}
+
 TEST_F(RegexpQueryTest, GetRegexPrefixWithDebugPoint) {
     // Test the debug point that forces get_regex_prefix to return nullopt
     // This covers the debug execute if code path
diff --git a/be/test/storage/index/inverted/query_v2/regexp_query_test.cpp 
b/be/test/storage/index/inverted/query_v2/regexp_query_test.cpp
index ed02ac578d3..aea4ed627ed 100644
--- a/be/test/storage/index/inverted/query_v2/regexp_query_test.cpp
+++ b/be/test/storage/index/inverted/query_v2/regexp_query_test.cpp
@@ -28,7 +28,6 @@
 #include "storage/index/index_query_context.h"
 #include "storage/index/inverted/analyzer/custom_analyzer.h"
 #include "storage/index/inverted/query_v2/regexp_query/regexp_weight.h"
-#include "storage/index/inverted/query_v2/term_query/term_query.h"
 #include "storage/index/inverted/util/string_helper.h"
 
 CL_NS_USE(search)
@@ -59,13 +58,10 @@ public:
 private:
     void create_test_index(const std::string& field_name, const std::string& 
dir) {
         std::vector<std::string> test_data = {
-                "apple123",     "apple456",     "banana789",
-                "test123abc",   "pattern456",   "regex999",
-                "match123",     "search456",    "prefix123",
-                "suffix789",    "apple_test",   "banana_data",
-                "test_pattern", "data_regex",   "apple_banana",
-                "test_match",   "pattern_test", "prefix_suffix",
-                "abc123xyz",    "def456ghi",    "apple789 apple789 apple456"};
+                "apple123",   "apple456",     "banana789",     "test123abc", 
"pattern456",
+                "regex999",   "match123",     "search456",     "prefix123",  
"suffix789",
+                "apple_test", "banana_data",  "test_pattern",  "data_regex", 
"apple_banana",
+                "test_match", "pattern_test", "prefix_suffix", "abc123xyz",  
"def456ghi"};
 
         CustomAnalyzerConfig::Builder builder;
         builder.with_tokenizer_config("standard", {});
@@ -171,53 +167,6 @@ TEST_F(RegexpQueryV2Test, test_regexp_query_with_scoring) {
     ASSERT_NE(regexp_weight, nullptr);
 }
 
-TEST_F(RegexpQueryV2Test, test_regexp_query_scores_matching_terms) {
-    auto context = std::make_shared<IndexQueryContext>();
-    context->collection_statistics = std::make_shared<CollectionStatistics>();
-    context->collection_similarity = std::make_shared<CollectionSimilarity>();
-
-    auto* dir = FSDirectory::getDirectory(kTestDir.c_str());
-    auto reader_holder = 
make_shared_reader(lucene::index::IndexReader::open(dir, true));
-    ASSERT_NE(reader_holder, nullptr);
-
-    std::wstring field = StringHelper::to_wstring("content");
-    auto query = std::make_shared<query_v2::RegexpQuery>(context, field, 
"apple.*");
-    auto weight = query->weight(true);
-
-    query_v2::QueryExecutionContext exec_ctx;
-    exec_ctx.segment_num_rows = reader_holder->maxDoc();
-    exec_ctx.readers = {reader_holder};
-    exec_ctx.field_reader_bindings.emplace(field, reader_holder);
-
-    auto statistics = context->collection_statistics;
-    statistics->_total_num_docs = reader_holder->maxDoc();
-    statistics->_total_num_tokens[field] =
-            
reader_holder->sumTotalTermFreq(field.c_str()).value_or(reader_holder->maxDoc());
-    for (const auto* term : {L"apple123", L"apple789", L"apple456"}) {
-        Term lucene_term(field.c_str(), term);
-        statistics->_term_doc_freqs[field][term] = 
reader_holder->docFreq(&lucene_term);
-    }
-    auto term_score = [&](const wchar_t* term, uint32_t doc_id) {
-        auto term_query = std::make_shared<query_v2::TermQuery>(context, 
field, term);
-        auto term_scorer = term_query->weight(true)->scorer(exec_ctx);
-        EXPECT_EQ(term_scorer->seek(doc_id), doc_id);
-        return term_scorer->score();
-    };
-
-    auto scorer = weight->scorer(exec_ctx);
-    ASSERT_EQ(scorer->seek(0), 0);
-    float single_term_score = scorer->score();
-    EXPECT_NE(single_term_score, 1.0F);
-    EXPECT_FLOAT_EQ(single_term_score, term_score(L"apple123", 0));
-    uint32_t last_doc = reader_holder->maxDoc() - 1;
-    ASSERT_EQ(scorer->seek(last_doc), last_doc);
-    EXPECT_GT(scorer->score(), single_term_score);
-    EXPECT_NEAR(scorer->score(),
-                term_score(L"apple789", last_doc) + term_score(L"apple456", 
last_doc), 1e-5F);
-
-    _CLDECDELETE(dir);
-}
-
 // Test regexp query execution
 TEST_F(RegexpQueryV2Test, test_regexp_query_execution) {
     auto context = std::make_shared<IndexQueryContext>();
@@ -625,7 +574,7 @@ TEST_F(RegexpQueryV2Test, 
test_make_exact_match_wildcard_pattern) {
         doc = scorer->advance();
     }
 
-    EXPECT_EQ(result.cardinality(), 21);
+    EXPECT_EQ(result.cardinality(), 20);
 
     _CLDECDELETE(dir);
 }
diff --git a/be/test/storage/index/inverted/query_v2/wildcard_query_test.cpp 
b/be/test/storage/index/inverted/query_v2/wildcard_query_test.cpp
index 3807a2787db..af119cdd260 100644
--- a/be/test/storage/index/inverted/query_v2/wildcard_query_test.cpp
+++ b/be/test/storage/index/inverted/query_v2/wildcard_query_test.cpp
@@ -27,7 +27,6 @@
 #include "common/status.h"
 #include "storage/index/index_query_context.h"
 #include "storage/index/inverted/analyzer/custom_analyzer.h"
-#include "storage/index/inverted/query_v2/term_query/term_query.h"
 #include "storage/index/inverted/query_v2/wildcard_query/wildcard_weight.h"
 #include "storage/index/inverted/util/string_helper.h"
 
@@ -58,20 +57,14 @@ public:
 
 private:
     void create_test_index(const std::string& field_name, const std::string& 
dir) {
-        std::vector<std::string> test_data = {"apple",     "application", 
"apply",
-                                              "apricot",   "banana",      
"band",
-                                              "bandana",   "can",         
"candy",
-                                              "cat",       "catalog",     
"dog",
-                                              "document",  "door",        
"hello",
-                                              "help",      "helpful",     
"test",
-                                              "testing",   "testcase",    
"wildcard",
-                                              "wild",      "wilderness",  
"card",
-                                              "cardboard", "abc",         
"abcd",
-                                              "abcde",     "prefix123",   
"123suffix",
-                                              "pre123",    "123suf",      
"both123both",
-                                              "star",      "start",       
"started",
-                                              "starter",   "question",    
"quest",
-                                              "query",     "queries",     
"test test testing"};
+        std::vector<std::string> test_data = {
+                "apple",     "application", "apply",       "apricot", 
"banana",     "band",
+                "bandana",   "can",         "candy",       "cat",     
"catalog",    "dog",
+                "document",  "door",        "hello",       "help",    
"helpful",    "test",
+                "testing",   "testcase",    "wildcard",    "wild",    
"wilderness", "card",
+                "cardboard", "abc",         "abcd",        "abcde",   
"prefix123",  "123suffix",
+                "pre123",    "123suf",      "both123both", "star",    "start", 
     "started",
+                "starter",   "question",    "quest",       "query",   
"queries"};
 
         CustomAnalyzerConfig::Builder builder;
         builder.with_tokenizer_config("standard", {});
@@ -162,53 +155,6 @@ TEST_F(WildcardQueryV2Test, 
test_wildcard_query_with_scoring) {
     ASSERT_NE(wildcard_weight, nullptr);
 }
 
-TEST_F(WildcardQueryV2Test, test_wildcard_query_scores_matching_terms) {
-    auto context = std::make_shared<IndexQueryContext>();
-    context->collection_statistics = std::make_shared<CollectionStatistics>();
-    context->collection_similarity = std::make_shared<CollectionSimilarity>();
-
-    auto* dir = FSDirectory::getDirectory(kTestDir.c_str());
-    auto reader_holder = 
make_shared_reader(lucene::index::IndexReader::open(dir, true));
-    ASSERT_NE(reader_holder, nullptr);
-
-    std::wstring field = StringHelper::to_wstring("field");
-    auto query = std::make_shared<query_v2::WildcardQuery>(context, field, 
"test*");
-    auto weight = query->weight(true);
-
-    query_v2::QueryExecutionContext exec_ctx;
-    exec_ctx.segment_num_rows = reader_holder->maxDoc();
-    exec_ctx.readers = {reader_holder};
-    exec_ctx.field_reader_bindings.emplace(field, reader_holder);
-
-    auto statistics = context->collection_statistics;
-    statistics->_total_num_docs = reader_holder->maxDoc();
-    statistics->_total_num_tokens[field] =
-            
reader_holder->sumTotalTermFreq(field.c_str()).value_or(reader_holder->maxDoc());
-    for (const auto* term : {L"test", L"testing"}) {
-        Term lucene_term(field.c_str(), term);
-        statistics->_term_doc_freqs[field][term] = 
reader_holder->docFreq(&lucene_term);
-    }
-    auto term_score = [&](const wchar_t* term, uint32_t doc_id) {
-        auto term_query = std::make_shared<query_v2::TermQuery>(context, 
field, term);
-        auto term_scorer = term_query->weight(true)->scorer(exec_ctx);
-        EXPECT_EQ(term_scorer->seek(doc_id), doc_id);
-        return term_scorer->score();
-    };
-
-    auto scorer = weight->scorer(exec_ctx);
-    ASSERT_EQ(scorer->seek(17), 17);
-    float single_term_score = scorer->score();
-    EXPECT_NE(single_term_score, 1.0F);
-    EXPECT_FLOAT_EQ(single_term_score, term_score(L"test", 17));
-    uint32_t last_doc = reader_holder->maxDoc() - 1;
-    ASSERT_EQ(scorer->seek(last_doc), last_doc);
-    EXPECT_GT(scorer->score(), single_term_score);
-    EXPECT_NEAR(scorer->score(), term_score(L"test", last_doc) + 
term_score(L"testing", last_doc),
-                1e-5F);
-
-    _CLDECDELETE(dir);
-}
-
 // Test wildcard query with asterisk prefix pattern
 TEST_F(WildcardQueryV2Test, test_wildcard_query_prefix_pattern) {
     auto context = std::make_shared<IndexQueryContext>();
@@ -578,4 +524,4 @@ TEST_F(WildcardQueryV2Test, 
test_wildcard_query_move_semantics) {
     ASSERT_NE(weight2, nullptr);
 }
 
-} // namespace doris::segment_v2
+} // namespace doris::segment_v2
\ No newline at end of file
diff --git a/be/test/storage/segment/index_reader_helper_test.cpp 
b/be/test/storage/segment/index_reader_helper_test.cpp
index ca7a1ea5c80..352d6853249 100644
--- a/be/test/storage/segment/index_reader_helper_test.cpp
+++ b/be/test/storage/segment/index_reader_helper_test.cpp
@@ -439,6 +439,32 @@ TEST_F(IndexReaderHelperTest, 
NormalizerOnlyPhraseAndScoringNeedNoPositions) {
             InvertedIndexQueryType::MATCH_ANY_QUERY, &custom_meta));
 }
 
+TEST_F(IndexReaderHelperTest, RegexpScoresConstantOnEveryIndex) {
+    // A regexp scores a constant 1 and reads no statistics, so neither the 
analyzer nor phrase
+    // support decides whether it scores.
+    for (const auto& properties : std::vector<std::map<std::string, 
std::string>> {
+                 {},
+                 {{"parser", "none"}},
+                 {{"parser", "english"}},
+                 {{"parser", "english"}, {"support_phrase", "true"}},
+                 {{"normalizer", "split_norm"}}}) {
+        SCOPED_TRACE(::testing::PrintToString(properties));
+        TabletIndexPB pb;
+        pb.set_index_id(1);
+        pb.set_index_name("regexp_index");
+        pb.set_index_type(IndexType::INVERTED);
+        pb.add_col_unique_id(1);
+        for (const auto& [key, value] : properties) {
+            (*pb.mutable_properties())[key] = value;
+        }
+        TabletIndex index;
+        index.init_from_pb(pb);
+        
EXPECT_TRUE(IndexReaderHelper::is_need_similarity_score(TExprOpcode::MATCH_REGEXP,
 &index));
+        EXPECT_TRUE(IndexReaderHelper::is_need_similarity_score(
+                InvertedIndexQueryType::MATCH_REGEXP_QUERY, &index));
+    }
+}
+
 TEST_F(IndexReaderHelperTest, IsNeedSimilarityScoreWithTExprOpcodeTest) {
     TabletIndex index_meta;
     auto index_meta_pb = std::make_unique<TabletIndexPB>();
diff --git a/regression-test/data/search/test_search_score_pattern_constant.out 
b/regression-test/data/search/test_search_score_pattern_constant.out
new file mode 100644
index 00000000000..f2a3c30f31d
--- /dev/null
+++ b/regression-test/data/search/test_search_score_pattern_constant.out
@@ -0,0 +1,75 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !V2_search_regexp --
+2      1
+3      1
+6      1
+
+-- !V2_search_wildcard --
+2      1
+3      1
+6      1
+
+-- !V2_search_prefix --
+2      1
+3      1
+6      1
+
+-- !V2_search_keyword_regexp --
+6      1
+7      1
+
+-- !V2_match_regexp --
+2      1
+3      1
+6      1
+
+-- !V2_match_and_match_regexp --
+2      2.023573
+
+-- !V2_search_and_regexp --
+2      2.023573
+
+-- !V2_match_only --
+2      1.023573
+5      1.163151
+
+-- !V2_match_and_equality --
+2      1.023573
+
+-- !V3_search_regexp --
+2      1
+3      1
+6      1
+
+-- !V3_search_wildcard --
+2      1
+3      1
+6      1
+
+-- !V3_search_prefix --
+2      1
+3      1
+6      1
+
+-- !V3_search_keyword_regexp --
+6      1
+7      1
+
+-- !V3_match_regexp --
+2      1
+3      1
+6      1
+
+-- !V3_match_and_match_regexp --
+2      2.023573
+
+-- !V3_search_and_regexp --
+2      2.023573
+
+-- !V3_match_only --
+2      1.023573
+5      1.163151
+
+-- !V3_match_and_equality --
+2      1.023573
+
diff --git a/regression-test/data/search/test_search_score_regexp_wildcard.out 
b/regression-test/data/search/test_search_score_regexp_wildcard.out
deleted file mode 100644
index 393a5781dab..00000000000
--- a/regression-test/data/search/test_search_score_regexp_wildcard.out
+++ /dev/null
@@ -1,337 +0,0 @@
--- This file is automatically generated. You should know what you did if you 
want to edit this
--- !V2_standard_unscored_regexp --
-1
-2
-3
-4
-7
-8
-
--- !V2_standard_unscored_wildcard --
-1
-2
-3
-4
-7
-8
-
--- !V2_standard_false_regexp --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V2_standard_false_wildcard --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V2_standard_false_terms --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V2_standard_false_ascending --
-1      0.584433
-2      0.655108
-3      1.120813
-7      1.248584
-4      1.312985
-8      2.087193
-
--- !V2_standard_false_missing --
-
--- !V2_standard_true_regexp --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V2_standard_true_wildcard --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V2_standard_true_terms --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V2_standard_true_ascending --
-1      0.584433
-2      0.655108
-3      1.120813
-7      1.248584
-4      1.312985
-8      2.087193
-
--- !V2_standard_true_missing --
-
--- !V2_none_unscored_regexp --
-1
-2
-3
-4
-7
-8
-
--- !V2_none_unscored_wildcard --
-1
-2
-3
-4
-7
-8
-
--- !V2_none_false_regexp --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V2_none_false_wildcard --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V2_none_false_terms --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V2_none_false_ascending --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V2_none_false_missing --
-
--- !V2_none_true_regexp --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V2_none_true_wildcard --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V2_none_true_terms --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V2_none_true_ascending --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V2_none_true_missing --
-
--- !V3_standard_unscored_regexp --
-1
-2
-3
-4
-7
-8
-
--- !V3_standard_unscored_wildcard --
-1
-2
-3
-4
-7
-8
-
--- !V3_standard_false_regexp --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V3_standard_false_wildcard --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V3_standard_false_terms --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V3_standard_false_ascending --
-1      0.584433
-2      0.655108
-3      1.120813
-7      1.248584
-4      1.312985
-8      2.087193
-
--- !V3_standard_false_missing --
-
--- !V3_standard_true_regexp --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V3_standard_true_wildcard --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V3_standard_true_terms --
-8      2.087193
-4      1.312985
-7      1.248584
-3      1.120813
-2      0.655108
-1      0.584433
-
--- !V3_standard_true_ascending --
-1      0.584433
-2      0.655108
-3      1.120813
-7      1.248584
-4      1.312985
-8      2.087193
-
--- !V3_standard_true_missing --
-
--- !V3_none_unscored_regexp --
-1
-2
-3
-4
-7
-8
-
--- !V3_none_unscored_wildcard --
-1
-2
-3
-4
-7
-8
-
--- !V3_none_false_regexp --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V3_none_false_wildcard --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V3_none_false_terms --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V3_none_false_ascending --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V3_none_false_missing --
-
--- !V3_none_true_regexp --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V3_none_true_wildcard --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V3_none_true_terms --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V3_none_true_ascending --
-1      1.791759
-2      1.791759
-3      1.791759
-4      1.791759
-7      1.791759
-8      1.791759
-
--- !V3_none_true_missing --
-
diff --git 
a/regression-test/suites/search/test_search_score_pattern_constant.groovy 
b/regression-test/suites/search/test_search_score_pattern_constant.groovy
new file mode 100644
index 00000000000..430f313b10f
--- /dev/null
+++ b/regression-test/suites/search/test_search_score_pattern_constant.groovy
@@ -0,0 +1,79 @@
+// 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.
+
+// score() of pattern queries follows Elasticsearch's default rewrite: a 
regexp, wildcard or
+// prefix in SEARCH and a MATCH_REGEXP score a constant 1 per matching row, 
whatever segment the
+// row is in, and add exactly 1 next to a scored clause. An equality predicate 
adds nothing.
+suite("test_search_score_pattern_constant", "p0") {
+    // SEARCH and MATCH need index execution even when CI fuzzes these session 
defaults.
+    sql "set enable_common_expr_pushdown = true"
+    sql "set enable_inverted_index_query = true"
+
+    for (def storageFormat : ["V2", "V3"]) {
+        sql "DROP TABLE IF EXISTS test_search_score_pattern_constant"
+        sql """
+            CREATE TABLE test_search_score_pattern_constant (
+                id BIGINT NOT NULL,
+                content STRING NULL,
+                tag STRING NULL,
+                INDEX idx_content(content) USING INVERTED
+                    PROPERTIES("parser" = "english", "support_phrase" = 
"true"),
+                INDEX idx_tag(tag) USING INVERTED
+            ) ENGINE=OLAP
+            DUPLICATE KEY(id)
+            DISTRIBUTED BY HASH(id) BUCKETS 1
+            PROPERTIES (
+                "replication_allocation" = "tag.location.default:1",
+                "inverted_index_storage_format" = "${storageFormat}",
+                "disable_auto_compaction" = "true"
+            )
+        """
+        // Two inserts make two segments with different term statistics; a 
constant score must not
+        // depend on them.
+        sql """INSERT INTO test_search_score_pattern_constant VALUES
+            (1, 'Apache Doris is a high performance analytical database', 
'doris'),
+            (2, 'Inverted indexes are suitable for full text search', 'index'),
+            (3, 'The parser splits text into multiple terms', 'parser'),
+            (4, 'Doris supports fast real time data analysis', 'doris'),
+            (5, 'Users can quickly search product names', 'search')
+        """
+        sql """INSERT INTO test_search_score_pattern_constant VALUES
+            (6, 'text text text', 'text'), (7, 'plain words only', 'textual')
+        """
+        sql "sync"
+
+        for (def query : [
+                ["search_regexp", "SEARCH('content:/.*ext/')"],
+                ["search_wildcard", "SEARCH('content:*ext')"],
+                ["search_prefix", "SEARCH('content:te*')"],
+                ["search_keyword_regexp", "SEARCH('tag:/text.*/')"],
+                ["match_regexp", "content MATCH_REGEXP 'ext'"],
+                // A pattern next to a scored clause adds exactly 1, as an 
Elasticsearch bool must
+                // with a regexp clause does.
+                ["match_and_match_regexp", "content MATCH 'search' AND content 
MATCH_REGEXP 'ext'"],
+                ["search_and_regexp", "SEARCH('content:search AND 
content:/.*ext/')"],
+                ["match_only", "content MATCH 'search'"],
+                ["match_and_equality", "content MATCH 'search' AND tag = 
'index'"]]) {
+            quickTest("${storageFormat}_${query[0]}", """
+                SELECT id, ROUND(s, 6) FROM (
+                    SELECT id, score() AS s FROM 
test_search_score_pattern_constant
+                    WHERE ${query[1]} ORDER BY s DESC LIMIT 10
+                ) hits ORDER BY id
+            """, true)
+        }
+    }
+}
diff --git 
a/regression-test/suites/search/test_search_score_regexp_wildcard.groovy 
b/regression-test/suites/search/test_search_score_regexp_wildcard.groovy
deleted file mode 100644
index 01cd72c70a7..00000000000
--- a/regression-test/suites/search/test_search_score_regexp_wildcard.groovy
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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.
-
-suite("test_search_score_regexp_wildcard", "p0") {
-    sql "set enable_common_expr_pushdown = true"
-    sql "set enable_inverted_index_query = true"
-
-    def scoredQuery = { predicate, direction, limit ->
-        """
-            SELECT id, ROUND(bm25_score, 6)
-            FROM (
-                SELECT id, score() AS bm25_score
-                FROM test_search_score_regexp_wildcard
-                WHERE ${predicate}
-                ORDER BY bm25_score ${direction} LIMIT ${limit}
-            ) hits
-            ORDER BY bm25_score ${direction}, id
-        """
-    }
-    for (String storageFormat : ["V2", "V3"]) {
-        for (String parser : ["standard", "none"]) {
-            sql "DROP TABLE IF EXISTS test_search_score_regexp_wildcard"
-            sql """
-                CREATE TABLE test_search_score_regexp_wildcard (
-                    id INT NOT NULL,
-                    content STRING NULL,
-                    INDEX idx_content(content) USING INVERTED 
PROPERTIES("parser" = "${parser}")
-                ) ENGINE=OLAP
-                DUPLICATE KEY(id)
-                DISTRIBUTED BY HASH(id) BUCKETS 1
-                PROPERTIES (
-                    "replication_allocation" = "tag.location.default:1",
-                    "inverted_index_storage_format" = "${storageFormat}"
-                )
-            """
-            sql """
-                INSERT INTO test_search_score_regexp_wildcard VALUES
-                    (1, 'apple'), (2, 'apple apple apple'), (3, 'application'),
-                    (4, 'apple application'), (5, 'banana'), (6, NULL),
-                    (7, 'apple application apple'), (8, 'apply apple')
-            """
-            sql "sync"
-            String regexp = "search('content:/app.*/', 
'{\"mode\":\"lucene\"}')"
-            String wildcard = "search('content:*pp*', '{\"mode\":\"lucene\"}')"
-            String terms = parser == "standard"
-                    ? "search('content:apple OR content:application OR 
content:apply', '{\"mode\":\"lucene\"}')"
-                    : "search('content:EXACT(apple) OR content:EXACT(apple 
apple apple) OR content:EXACT(application) OR content:EXACT(apple application) 
OR content:EXACT(apple application apple) OR content:EXACT(apply apple)', 
'{\"mode\":\"standard\"}')"
-            String label = "${storageFormat}_${parser}"
-            quickTest("${label}_unscored_regexp", """
-                SELECT id FROM test_search_score_regexp_wildcard WHERE 
${regexp} ORDER BY id
-            """)
-            quickTest("${label}_unscored_wildcard", """
-                SELECT id FROM test_search_score_regexp_wildcard WHERE 
${wildcard} ORDER BY id
-            """)
-            for (boolean wand : [false, true]) {
-                sql "set enable_inverted_index_wand_query = ${wand}"
-                quickTest("${label}_${wand}_regexp", scoredQuery(regexp, 
"DESC", 100))
-                quickTest("${label}_${wand}_wildcard", scoredQuery(wildcard, 
"DESC", 100))
-                quickTest("${label}_${wand}_terms", scoredQuery(terms, "DESC", 
100))
-                quickTest("${label}_${wand}_ascending", scoredQuery(regexp, 
"ASC", 100))
-                quickTest("${label}_${wand}_missing", scoredQuery(
-                        "search('content:/missing.*/', 
'{\"mode\":\"lucene\"}')", "DESC", 100))
-            }
-        }
-    }
-}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to