feat(wiki): add mate_wiki_relation cache table for page-to-page edges

This commit is contained in:
matevip 2026-05-02 19:04:06 +08:00
parent 19b82cdc2a
commit d0706239ea
4 changed files with 206 additions and 0 deletions

View File

@ -0,0 +1,75 @@
package vip.mate.wiki.model;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* Persistent cache of page-to-page multi-signal relations.
*
* <p>One row per ordered (page_a_id, page_b_id) pair within a knowledge base.
* The row materializes the aggregate score across registered signal strategies
* plus optional taxonomy / confidence / evidence metadata when the planning
* stage of the compile pipeline produced any.
*
* <p>Distinct from {@link WikiPageCitationEntity}, which models page-to-chunk
* citations. The two tables coexist; nothing in this row supersedes citation
* rows.
*
* @author MateClaw Team
*/
@Data
@TableName("mate_wiki_relation")
public class WikiRelationEntity {
@TableId(type = IdType.AUTO)
private Long id;
private Long kbId;
private Long pageAId;
private Long pageBId;
/** Aggregate score (sum of weighted signal contributions). */
private BigDecimal totalScore;
/** Per-signal breakdown serialized as JSON, e.g. {@code {"direct_link":2.0,"shared_chunk":5.0}}. */
private String signalsJson;
/** Relation taxonomy: {@code mention | cite | supports | contradicts | extends}. */
private String type;
/** Confidence taxonomy: {@code EXTRACTED | INFERRED | AMBIGUOUS | UNVERIFIED}. */
private String confidence;
/** Verbatim quote or paraphrased rationale supporting the relation; ≤ 500 chars. */
private String evidence;
/** When evidence is a quote, the raw material id it was pulled from. */
private Long evidenceRawId;
/** Provenance tag: {@code llm-extracted | wikilink-context | manual}. */
private String source;
private LocalDateTime computedAt;
/** Fingerprint of the inputs that produced {@link #totalScore}; used for cache invalidation. */
private String computedHash;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableLogic
private Integer deleted;
}

View File

@ -0,0 +1,22 @@
package vip.mate.wiki.repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import vip.mate.wiki.model.WikiRelationEntity;
/**
* Mapper for the page-to-page wiki relation cache.
*
* <p>Read paths fetch top-K rows by ({@code kb_id}, {@code page_a_id}) ordered
* by {@code total_score DESC}; write paths upsert (insert + on-duplicate-key
* update) keyed by ({@code kb_id}, {@code page_a_id}, {@code page_b_id}).
*
* <p>Cache invalidation paths use soft-delete (set {@code deleted=1}) keyed
* by either {@code page_id} or {@code kb_id}; the consuming services
* provide thin wrappers via custom SQL when needed.
*
* @author MateClaw Team
*/
@Mapper
public interface WikiRelationMapper extends BaseMapper<WikiRelationEntity> {
}

View File

@ -0,0 +1,66 @@
-- mate_wiki_relation: persistent cache of page-to-page multi-signal relations.
--
-- Distinct from mate_wiki_page_citation, which models page-to-chunk citations.
-- A row here represents one directed (or undirected, see notes below) edge in
-- the wiki page graph for a given knowledge base, materializing:
-- * the aggregate relevance score across registered signal strategies
-- (direct link, shared chunk, shared raw, semantic similarity, ...)
-- * a per-signal breakdown for explainability
-- * an optional taxonomy tag (mention / cite / supports / contradicts /
-- extends) populated by the planning stage of the compile pipeline
-- * confidence + evidence snippets sourced from the same compile output
-- * cache invalidation metadata so readers can decide whether to recompute
CREATE TABLE IF NOT EXISTS mate_wiki_relation (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
kb_id BIGINT NOT NULL,
page_a_id BIGINT NOT NULL,
page_b_id BIGINT NOT NULL,
-- Aggregate relevance score (sum of weighted signal contributions).
total_score DECIMAL(8, 4),
-- Per-signal breakdown, e.g. {"direct_link":2.0,"shared_chunk":5.0}.
signals_json CLOB,
-- Relation type taxonomy: mention | cite | supports | contradicts | extends.
type VARCHAR(32),
-- Confidence taxonomy: EXTRACTED | INFERRED | AMBIGUOUS | UNVERIFIED.
confidence VARCHAR(16),
-- Verbatim or paraphrased justification (≤ 500 chars enforced in Java layer).
evidence CLOB,
-- When evidence is a quote, the raw material id it was pulled from.
evidence_raw_id BIGINT,
-- Provenance tag: llm-extracted | wikilink-context | manual.
source VARCHAR(32),
-- Cache invalidation metadata.
computed_at TIMESTAMP,
computed_hash VARCHAR(64),
-- Standard rows.
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted INT NOT NULL DEFAULT 0
);
-- Unique edge identity within a KB (deleted column included so soft-deleted
-- rows can coexist with re-inserted ones during re-compute cycles).
CREATE UNIQUE INDEX IF NOT EXISTS uk_wr_pair
ON mate_wiki_relation (kb_id, page_a_id, page_b_id, deleted);
-- "Top-K related to page X" queries.
CREATE INDEX IF NOT EXISTS idx_wr_page_a
ON mate_wiki_relation (kb_id, page_a_id, total_score DESC);
-- KB-wide ranking queries (e.g., strongest edges across the graph).
CREATE INDEX IF NOT EXISTS idx_wr_kb_score
ON mate_wiki_relation (kb_id, total_score DESC);
-- Cache invalidator scans (e.g., "everything older than X").
CREATE INDEX IF NOT EXISTS idx_wr_computed_at
ON mate_wiki_relation (computed_at);

View File

@ -0,0 +1,43 @@
-- mate_wiki_relation: persistent cache of page-to-page multi-signal relations.
--
-- Distinct from mate_wiki_page_citation, which models page-to-chunk citations.
-- A row here represents one directed (or undirected, see notes below) edge in
-- the wiki page graph for a given knowledge base, materializing:
-- * the aggregate relevance score across registered signal strategies
-- (direct link, shared chunk, shared raw, semantic similarity, ...)
-- * a per-signal breakdown for explainability
-- * an optional taxonomy tag (mention / cite / supports / contradicts /
-- extends) populated by the planning stage of the compile pipeline
-- * confidence + evidence snippets sourced from the same compile output
-- * cache invalidation metadata so readers can decide whether to recompute
CREATE TABLE IF NOT EXISTS mate_wiki_relation (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
kb_id BIGINT NOT NULL,
page_a_id BIGINT NOT NULL,
page_b_id BIGINT NOT NULL,
total_score DECIMAL(8, 4),
signals_json JSON,
type VARCHAR(32),
confidence VARCHAR(16),
evidence TEXT,
evidence_raw_id BIGINT,
source VARCHAR(32),
computed_at DATETIME(3),
computed_hash VARCHAR(64),
create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
deleted TINYINT NOT NULL DEFAULT 0,
UNIQUE KEY uk_wr_pair (kb_id, page_a_id, page_b_id, deleted),
KEY idx_wr_page_a (kb_id, page_a_id, total_score DESC),
KEY idx_wr_kb_score (kb_id, total_score DESC),
KEY idx_wr_computed_at (computed_at)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci
COMMENT = 'Page-to-page wiki relation cache (multi-signal score, taxonomy, confidence, provenance).';