using Dpz.Core.Entity.Base;
using Dpz.Core.Entity.Base.Indexes;

namespace Dpz.Core.Public.Entity;

/// <summary>
/// 站点地图文件记录(每次生成按文件保存一份,旧记录由 TTL 索引自动清理)
/// </summary>
[BsonIgnoreExtraElements]
public class SitemapDocument : BaseEntity, IIndexedEntity<SitemapDocument>
{
    /// <summary>
    /// 站点地图文件名(如 sitemap.xml、article-sitemap.xml)
    /// </summary>
    public required string Name { get; set; }

    /// <summary>
    /// 生成日期
    /// </summary>
    [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
    public required DateTime Date { get; set; }

    /// <summary>
    /// 站点地图完整 XML 内容
    /// </summary>
    public required string Xml { get; set; }

    /// <summary>
    /// 包含的 URL 数量
    /// </summary>
    public int UrlCount { get; set; }

    /// <summary>
    /// XML 内容字节数
    /// </summary>
    public int ByteCount { get; set; }

    /// <inheritdoc />
    public static IReadOnlyList<EntityIndexDefinition> GetIndexDefinitions() =>
        [
            new()
            {
                Fields =
                [
                    EntityIndexField.Ascending<SitemapDocument>(x => x.Name),
                    EntityIndexField.Descending<SitemapDocument>(x => x.Date),
                ],
            },
            new()
            {
                Fields = [EntityIndexField.Ascending<SitemapDocument>(x => x.Date)],
                ExpireAfter = TimeSpan.FromDays(7),
            },
        ];
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这段代码定义了一个用于 MongoDB 存储的实体类 SitemapDocument,用来记录站点地图(Sitemap)的生成文件内容,并利用 MongoDB 的 TTL(生存时间)索引自动清理旧记录。下面逐部分解释:


1. 命名空间与引用

using Dpz.Core.Entity.Base;
using Dpz.Core.Entity.Base.Indexes;
  • BaseEntity:可能是所有持久化实体的基类,通常包含 Id(如 ObjectId)等公共字段。
  • IIndexedEntity<T>:一个泛型接口,要求实现静态方法 GetIndexDefinitions(),用于定义 MongoDB 集合的索引。

2. 类声明与特性

[BsonIgnoreExtraElements]
public class SitemapDocument : BaseEntity, IIndexedEntity<SitemapDocument>
  • [BsonIgnoreExtraElements]:告诉 MongoDB 序列化器在反序列化时忽略文档中多余的字段,这样即使数据库中有旧格式的额外字段,也不会导致反序列化失败。
  • 继承 BaseEntity 并实现 IIndexedEntity<SitemapDocument>,表示该实体拥有自己的自定义索引定义。

3. 属性说明

属性类型说明
Namestring站点地图文件名(如 sitemap.xml、article-sitemap.xml),使用 required 修饰表示必须赋值。
DateDateTime生成日期,使用 [BsonDateTimeOptions(Kind = DateTimeKind.Local)] 指定存储时按本地时间处理。
Xmlstring完整的站点地图 XML 内容,required 必填。
UrlCountint该地图中包含的 URL 数量,用于统计。
ByteCountintXML 内容的字节数,可用于粗略估算存储占用。

这些属性都使用了 C# 11 的 required 关键字,在对象初始化时必须显式赋值,增强代码的健壮性。


4. 索引定义

public static IReadOnlyList<EntityIndexDefinition> GetIndexDefinitions() =>
[
    new()
    {
        Fields =
        [
            EntityIndexField.Ascending<SitemapDocument>(x => x.Name),
            EntityIndexField.Descending<SitemapDocument>(x => x.Date),
        ],
    },
    new()
    {
        Fields = [EntityIndexField.Ascending<SitemapDocument>(x => x.Date)],
        ExpireAfter = TimeSpan.FromDays(7),
    },
];

这里定义了两种索引:

索引 1:复合索引(Name + Date)

  • Name 升序,Date 降序。
  • 用途:支持按文件名查询最新生成的站点地图记录。例如想获取 sitemap.xml 的最新一条记录,可以快速查询并按日期倒序排序。

索引 2:TTL 索引(自动过期)

  • 字段:Date 升序。
  • ExpireAfter = TimeSpan.FromDays(7):MongoDB 会定期删除 Date 字段值超过 7 天的文档。
  • 这是实现“旧记录自动清理”的关键:每次生成新的站点地图时保存为新文档,7 天前的记录会被数据库自动删除,无需手动维护清理逻辑。

5. 整体设计意图

该类用于存储站点地图的“历史版本”:

  • 每次生成一个站点地图文件(如 sitemap.xml)时,都会插入一条新记录,包含文件名、生成时间、XML 内容和统计信息。
  • 由于 TTL 索引的存在,MongoDB 会自动清理 7 天前的旧数据,避免集合无限增长。
  • 复合索引则加速了对某个站点地图文件最新版本的查询,方便在需要时快速获取最近生成的 sitemap 内容。

小结

这段代码是一个典型的 MongoDB 实体设计,结合了 C# 的可空性特性和 Mongo 的索引机制,实现了带自动过期清理的站点地图历史记录存储,既保证查询性能,又简化了数据维护。

评论加载中...