github-actions[bot] commented on code in PR #69698:
URL: https://github.com/apache/doris/pull/69698#discussion_r4396102407


##########
be/src/storage/index/inverted/reader/collection_statistics.cpp:
##########
@@ -117,6 +119,56 @@ void add_term_doc_frequency(
     (*logical_frequencies)[field][logical_term] += doc_frequency;
 }
 
+Status segment_scoring_terms(index_query::IndexSource& source, const 
CollectInfo& collect_info,
+                             const VisibleDocFreq& visible_doc_freq,
+                             FieldPrefixExpansions* expansions, 
std::vector<std::string>* terms) {
+    DORIS_CHECK(expansions != nullptr);
+    DORIS_CHECK(terms != nullptr);
+    *terms = collect_info.unique_terms;
+    std::unordered_set<std::string> listed(terms->begin(), terms->end());
+    for (const auto& scoring_prefix : collect_info.scoring_prefixes) {
+        index_query::TermPattern pattern;
+        
RETURN_IF_ERROR(index_query::TermPattern::create(index_query::TermPatternKind::kPrefix,
+                                                         
scoring_prefix.prefix, &pattern));
+        const auto wanted = static_cast<size_t>(scoring_prefix.max_expansions);
+        std::vector<std::string> visible;
+        for (int32_t limit = scoring_prefix.max_expansions;; limit *= 2) {
+            std::vector<std::string> expanded;
+            RETURN_IF_ERROR(source.expand_terms(pattern, limit, &expanded));
+            visible.clear();
+            for (auto& term : expanded) {
+                uint64_t doc_freq = 0;
+                RETURN_IF_ERROR(visible_doc_freq(term, &doc_freq));
+                if (doc_freq > 0) {
+                    visible.push_back(std::move(term));
+                }
+            }
+            // The dictionary ran out of terms, or the first `wanted` visible 
ones are found.
+            if (expanded.size() < static_cast<size_t>(limit) || visible.size() 
>= wanted) {
+                break;
+            }
+        }
+        // A read with doubled limit can find more visible terms than the 
prefix keeps; the
+        // dictionary order puts the ones to keep first.
+        if (visible.size() > wanted) {
+            visible.resize(wanted);
+        }
+        auto& prefix_terms =
+                expansions
+                        
->try_emplace(segment_v2::inverted_index::StringHelper::to_wstring(
+                                              scoring_prefix.prefix),
+                                      scoring_prefix.max_expansions)
+                        .first->second;
+        for (auto& term : visible) {
+            
prefix_terms.insert(segment_v2::inverted_index::StringHelper::to_wstring(term));

Review Comment:
   [P2] Preserve raw SNII term identity in prefix statistics
   
   SNII preserves raw token bytes, but this conversion uses Boost's default 
[skip-invalid 
policy](https://www.boost.org/doc/libs/1_84_0/libs/locale/doc/html/group__codepage.html),
 so distinct dictionary terms can become the same key. A whitespace 
`char_group` analyzer with no filters and `support_phrase=true` can index one 
row containing `CONCAT('apple ra r', UNHEX('FF'), 'a r', UNHEX('FE'), 'a')`: 
the tokenizer retains invalid bytes inside each token. For the valid query 
`MATCH_PHRASE_PREFIX 'apple r'` at the default cap, all three distinct `r...a` 
expansions become `L"ra"`. The frequency loop counts each raw term once and 
accumulates them under that wide key, yielding `df(ra)=3` with `N=1`; the 
per-raw-term SNII bounds checks do not catch this collision. The scorer then 
uses `idf(apple)+idf(ra)=log(4/3)+log(4/7)=-0.2719`, so `score()>0` drops the 
matching row. Before this change the ASCII query did not collect those 
malformed dictionary terms. Preserve lossless raw-term identity an
 d dictionary order through expansion storage and frequency lookup, and add 
SNII coverage for malformed dictionary tokens.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to