Skip to content

feat: add compound preset time rules for semantic search - #372

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
Johnson-zs:agent/bugfix/8f3298f2
Jul 30, 2026
Merged

feat: add compound preset time rules for semantic search#372
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
Johnson-zs:agent/bugfix/8f3298f2

Conversation

@Johnson-zs

@Johnson-zs Johnson-zs commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

根因分析

输入 去年12月创建的表格 搜索结果为空。根因:TimeExtractor 每次只调用一次 match()(返回优先级最高的单条命中),time_last_year(priority 170) 先命中 去年 即返回,12月 不被任何时间规则消费,漏成 keyword 12月,最终把"按创建时间筛选"误变成"按字面量 12月 筛选"。

  • timeextractor.cpp:30 — 单次 match() 只取一个时间命中
  • semanticruleengine.cpp:124match() 命中首条即返回
  • time_rules.json — 缺「预设年份+月份」组合规则

修复方案

新增 6 条高优先级复合时间规则(priority 高于对应纯预设规则),在 TimeExtractor 新增 3 个解析分支,将"预设年份+月份"、"预设周+星期几"、"预设月+日"合并为单一 Custom 时间区间:

规则 示例 priority
time_last_year_month 去年12月、上一年三月 175 (>170)
time_this_year_month 今年3月、本年十二月 175 (>170)
time_this_week_day 本周三、这周五 195 (>190)
time_last_week_day 上周一、上个星期五 195 (>190)
time_this_month_day 本月5号、当月十五日 185 (>180)
time_last_month_day 上个月15号、上月三号 185 (>180)

改动安全评估

改动为纯新增(6 条 JSON 规则 + 3 个私有方法 + 3 个 type 分支),不修改任何已有函数签名、不删除公开接口、不改变 match() 语义。低风险。

测试

tst_semantic_search.cpp 中补充:

  • tst_TimeExtraction:6 个新规则的正则命中/不命中测试
  • tst_IsSemanticQuery:7 个端到端测试(含核心回归 compoundTimeNoKeywordLeak),验证复合时间被整体消费、不漏 keyword、时间区间正确

Bug: https://pms.uniontech.com/bug-view-372155.html

Summary by Sourcery

Add support for compound preset time expressions in semantic search so that combined presets like year+month, week+weekday, and month+day are interpreted as single custom time ranges instead of leaking secondary components into keywords.

New Features:

  • Support parsing preset year+month expressions into custom month-long time ranges for the appropriate year.
  • Support parsing preset week+weekday expressions into custom single-day time ranges in this or last week.
  • Support parsing preset month+day expressions into custom single-day time ranges in this or last month.

Bug Fixes:

  • Prevent month and day parts of compound preset time expressions (e.g. “12月”) from leaking into keywords and breaking time-based semantic queries.

Tests:

  • Add unit tests for the new compound preset time rules at the extractor level to validate regex matching and metadata handling.
  • Add end-to-end semantic query tests to verify compound time spans are consumed as a single custom time constraint and that no keyword leakage occurs, including a dedicated regression case for the original failure.

1. 新增 time_last_year_month 规则,支持"去年12月""上一年三月"等预设年份+月份组合;
2. 新增 time_this_year_month 规则,支持"今年3月""本年十二月"等预设年份+月份组合;
3. 新增 time_this_week_day 规则,支持"本周三""这周五"等预设周+星期几组合;
4. 新增 time_last_week_day 规则,支持"上周一""上个星期五"等预设周+星期几组合;
5. 新增 time_this_month_day 规则,支持"本月5号""当月十五日"等预设月+日组合;
6. 新增 time_last_month_day 规则,支持"上个月15号""上月三号"等预设月+日组合;
7. 在 TimeExtractor 中新增 preset_year_month/preset_week_day/preset_month_day 三个解析分支;
8. 补充对应的单元测试覆盖所有新增规则及回归测试;

=====================================

1. added time_last_year_month rule for "last year + month" compound (e.g. 去年12月, 上一年三月);
2. added time_this_year_month rule for "this year + month" compound (e.g. 今年3月, 本年十二月);
3. added time_this_week_day rule for "this week + weekday" compound (e.g. 本周三, 这周五);
4. added time_last_week_day rule for "last week + weekday" compound (e.g. 上周一, 上个星期五);
5. added time_this_month_day rule for "this month + day" compound (e.g. 本月5号, 当月十五日);
6. added time_last_month_day rule for "last month + day" compound (e.g. 上个月15号, 上月三号);
7. added preset_year_month/preset_week_day/preset_month_day parsing branches in TimeExtractor;
8. added unit tests covering all new rules plus regression tests;

Log: 为语义搜索新增预设年份+月份、预设周+星期几、预设月+日的复合时间规则,解决"去年12月创建的表格"等复合时间查询结果为空的问题

Bug: https://pms.uniontech.com/bug-view-372155.html

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Johnson-zs, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Johnson-zs

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds new compound preset time rules and corresponding parsing branches so that phrases like "去年12月" are consumed as a single time span instead of leaking the month part into keywords, plus comprehensive unit and integration tests.

Sequence diagram for compound preset time parsing in semantic search

sequenceDiagram
    actor User
    participant SemanticRuleEngine
    participant TimeExtractor
    participant TimeConstraint

    User->>SemanticRuleEngine: submitQuery("去年12月创建的表格")
    SemanticRuleEngine->>SemanticRuleEngine: match(time_rules.json)
    SemanticRuleEngine->>TimeExtractor: extract(input, intent)
    TimeExtractor->>TimeExtractor: parsePresetYearMonth(match, metadata, tc)
    TimeExtractor->>TimeConstraint: setKind(TimeConstraintKind::Custom)
    TimeExtractor->>TimeConstraint: setCustomStart(QDateTime(monthStart,...))
    TimeExtractor->>TimeConstraint: setCustomEnd(QDateTime(monthEnd,...))
    SemanticRuleEngine-->>User: resultsFilteredByCustomMonthSpan
Loading

File-Level Changes

Change Details Files
Extend TimeExtractor to support new compound preset time types (year+month, week+weekday, month+day) mapped to custom time ranges.
  • Branch on new metadata types preset_year_month, preset_week_day, and preset_month_day in TimeExtractor::extract to invoke dedicated parsers.
  • Implement parsePresetYearMonth to convert a captured month plus preset (this/last year) into a Custom TimeConstraint spanning that calendar month.
  • Implement parsePresetWeekDay to map a captured weekday plus preset (this/last week) into a single-day Custom TimeConstraint within the appropriate week.
  • Implement parsePresetMonthDay to map a captured day plus preset (this/last month) into a single-day Custom TimeConstraint in the correct month, using locale-aware numeric parsing.
src/dfm-search/dfm-search-lib/semantic/extractors/timeextractor.cpp
src/dfm-search/dfm-search-lib/semantic/extractors/timeextractor.h
Introduce and validate new zh_CN time rules for compound preset expressions so higher-priority rules consume combined phrases instead of partial matches.
  • Define JSON rules (time_last_year_month, time_this_year_month, time_this_week_day, time_last_week_day, time_this_month_day, time_last_month_day) with priorities higher than the existing simple preset rules and with appropriate regex groups and metadata for month/day/weekday extraction.
  • Ensure regex patterns capture numeric and Chinese numeral forms, enforce required suffixes to avoid overmatching, and provide digit/weekday maps and preset flags used by the new parsers.
src/dfm-search/dfm-search-lib/semantic/rules/zh_CN/time_rules.json
Add unit tests for the new compound time rules at the regex level and end-to-end semantic query parsing to prevent keyword leakage and validate computed date ranges.
  • Extend tst_TimeExtraction with six new test slots to build each compound rule from JSON, assert matches and captured groups for various phrase forms, and verify non-matching edge cases.
  • Extend tst_IsSemanticQuery with seven new test slots that parse realistic Chinese queries, assert that the correct compound rule IDs are present in consumedSpans, that TimeConstraint kind is Custom with expected start/end dates, and that month/day fragments do not appear in intent keywords.
  • Add a focused regression test compoundTimeNoKeywordLeak to ensure that for several representative inputs (e.g. "去年12月创建的表格") the secondary time components (12月, 3月, 三, 五, 15号, 8号) never leak into keywords.
autotests/dfm-search-tests/tst_semantic_search.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:95分

■ 【总体评价】

代码实现了复合预设时间解析功能,修复了关键词泄漏问题,逻辑严谨且测试覆盖全面
代码质量高且无安全漏洞,仅在JSON配置中存在轻微的重复数据定义

■ 【详细分析】

  • 1.语法逻辑(完全正确)✓

TimeExtractor::parsePresetYearMonthparsePresetWeekDayparsePresetMonthDay 中,正确提取了月份、星期和日期,并进行了边界校验(如 month < 1 || month > 12)。日期计算逻辑使用 Qt 的 QDate 方法,正确处理了跨年和跨月的情况。
潜在问题:无
建议:无

  • 2.代码质量(优秀)✓

函数命名清晰表达了意图,符合规范。time_rules.json 中的规则配置结构清晰,新增的测试用例覆盖了阿拉伯数字、中文数字以及边界情况,注释说明了测试目的。
潜在问题:digit_map 在多条规则中重复定义,增加了维护成本。
建议:可以考虑在 JSON 配置层面支持引用或继承机制,减少重复配置。

  • 3.代码性能(高效)✓

新增的解析函数仅涉及简单的字符串转换和 QDate 计算,正则表达式匹配在初始化阶段完成,运行时开销极低。
潜在问题:无
建议:无

  • 4.代码安全(存在0个安全漏洞)✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
代码仅处理内部解析逻辑和日期计算,未涉及外部命令执行、数据库查询或敏感信息处理,无攻击面。

  • 建议:无

■ 【改进建议代码示例】

// time_rules.json 可以考虑提取公共配置,减少重复(示意)
// 虽然当前方式可行,但若规则增多,维护成本会上升
{
    "definitions": {
        "common_digit_map": {
            "零": 0, "一": 1, "二": 2, "两": 2, "三": 3, "四": 4,
            "五": 5, "六": 6, "七": 7, "八": 8, "九": 9, "十": 10
        }
    },
    "rules": [
        {
            "id": "time_last_year_month",
            "pattern": "(?:去年|上一年)(?<month>(?:\\d{1,2}|[零一二两三四五六七八九十]{1,3}))月份?",
            "metadata": {
                "type": "preset_year_month",
                "preset": "last_year",
                "digit_map_ref": "common_digit_map",
                "tens_unit": ""
            }
        }
    ]
}

@Johnson-zs

Copy link
Copy Markdown
Contributor Author

/forcemerge

@deepin-bot

deepin-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

This pr force merged! (status: blocked)

@deepin-bot
deepin-bot Bot merged commit 3085222 into linuxdeepin:master Jul 30, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants