当前位置: 首页 > news >正文

Coze源码分析-资源库-创建知识库-后端源码-应用/领域/数据访问

3. 应用服务层

3.1 知识库应用服务

文件位置: backend/application/knowledge/knowledge.go

func (k *KnowledgeApplicationService) CreateKnowledge(ctx context.Context, req *dataset.CreateDatasetRequest) (*dataset.CreateDatasetResponse, error) {// 1. 转换文档类型documentType := convertDocumentTypeDataset2Entity(req.FormatType)if documentType == model.DocumentTypeUnknown {return dataset.NewCreateDatasetResponse(), errors.New("unknown document type")}// 2. 用户身份验证uid := ctxutil.GetUIDFromCtx(ctx)if uid == nil {return nil, errorx.New(errno.ErrKnowledgePermissionCode, errorx.KV("msg", "session required"))}// 3. 构建创建请求createReq := service.CreateKnowledgeRequest{Name:        req.Name,Description: req.Description,CreatorID:   ptr.From(uid),SpaceID:     req.SpaceID,AppID:       req.GetProjectID(),FormatType:  documentType,IconUri:     req.IconURI,}if req.IconURI == "" {createReq.IconUri = getIconURI(req.GetFormatType())}// 4. 执行创建操作domainResp, err := k.DomainSVC.CreateKnowledge(ctx, &createReq)if err != nil {logs.CtxErrorf(ctx, "create knowledge failed, err: %v", err)return dataset.NewCreateDatasetResponse(), err}// 5. 发布创建事件var ptrAppID *int64if req.ProjectID != 0 {ptrAppID = ptr.Of(req.ProjectID)}err = k.eventBus.PublishResources(ctx, &resourceEntity.ResourceDomainEvent{OpType: resourceEntity.Created,Resource: &resourceEntity.ResourceDocument{ResType:       resource.ResType_Knowledge,ResID:         domainResp.KnowledgeID,Name:          ptr.Of(req.Name),ResSubType:    ptr.Of(int32(req.FormatType)),SpaceID:       ptr.Of(req.SpaceID),APPID:         ptrAppID,OwnerID:       ptr.Of(*uid),PublishStatus: ptr.Of(resource.PublishStatus_Published),PublishTimeMS: ptr.Of(domainResp.CreatedAtMs),CreateTimeMS:  ptr.Of(domainResp.CreatedAtMs),UpdateTimeMS:  ptr.Of(domainResp.CreatedAtMs),},})if err != nil {logs.CtxErrorf(ctx, "publish resource event failed, err: %v", err)return dataset.NewCreateDatasetResponse(), err}// 6. 返回创建结果return &dataset.CreateDatasetResponse{DatasetID: domainResp.KnowledgeID,}, nil
}

3.2 应用服务特点

知识库应用服务的主要特点:

  • 类型转换: 将前端请求的数据类型转换为领域层所需的类型
  • 身份验证: 从上下文中获取用户身份信息
  • 事件发布: 创建成功后发布资源创建事件,用于搜索索引等
  • 错误处理: 统一的错误处理和日志记录
  • 图标处理: 自动为知识库设置默认图标

3.3 事件驱动架构

知识库创建完成后,系统会发布资源创建事件:

// 发布创建事件
err = k.eventBus.PublishResources(ctx, &resourceEntity.ResourceDomainEvent{OpType: resourceEntity.Created,Resource: &resourceEntity.ResourceDocument{ResType:       resource.ResType_Knowledge,ResID:         domainResp.KnowledgeID,Name:          ptr.Of(req.Name),ResSubType:    ptr.Of(int32(req.FormatType)),SpaceID:       ptr.Of(req.SpaceID),APPID:         ptrAppID,OwnerID:       ptr.Of(*uid),PublishStatus: ptr.Of(resource.PublishStatus_Published),PublishTimeMS: ptr.Of(domainResp.CreatedAtMs),CreateTimeMS:  ptr.Of(domainResp.CreatedAtMs),UpdateTimeMS:  ptr.Of(domainResp.CreatedAtMs),},
})

这个事件会被搜索服务监听,用于更新搜索索引,确保新创建的知识库能够被搜索到。

4. 领域服务层

4.1 知识库领域服务

文件位置: backend/domain/knowledge/service/interface.go

知识库领域服务接口定义:

type Knowledge interface {CreateKnowledge(ctx context.Context, request *CreateKnowledgeRequest) (response *CreateKnowledgeResponse, err error)UpdateKnowledge(ctx context.Context, request *UpdateKnowledgeRequest) errorDeleteKnowledge(ctx context.Context, request *DeleteKnowledgeRequest) errorCopyKnowledge(ctx context.Context, request *CopyKnowledgeRequest) (*CopyKnowledgeResponse, error)MoveKnowledgeToLibrary(ctx context.Context, request *MoveKnowledgeToLibraryRequest) errorListKnowledge(ctx context.Context, request *ListKnowledgeRequest) (response *ListKnowledgeResponse, err error)GetKnowledgeByID(ctx context.Context, request *GetKnowledgeByIDRequest) (response *GetKnowledgeByIDResponse, err error)MGetKnowledgeByID(ctx context.Context, request *MGetKnowledgeByIDRequest) (response *MGetKnowledgeByIDResponse, err error)CreateDocument(ctx context.Context, request *CreateDocumentRequest) (response *CreateDocumentResponse, err error)UpdateDocument(ctx context.Context, request *UpdateDocumentRequest) errorDeleteDocument(ctx context.Context, request *DeleteDocumentRequest) errorListDocument(ctx context.Context, request *ListDocumentRequest) (response *ListDocumentResponse, err error)CreateSlice(ctx context.Context, request *CreateSliceRequest) (response *CreateSliceResponse, err error)UpdateSlice(ctx context.Context, request *UpdateSliceRequest) errorDeleteSlice(ctx context.Context, request *DeleteSliceRequest) errorListSlice(ctx context.Context, request *ListSliceRequest) (response *ListSliceResponse, err error)Retrieve(ctx context.Context, request *RetrieveRequest) (response *RetrieveResponse, err error)
}type CreateKnowledgeRequest struct {Name        stringDescription stringCreatorID   int64SpaceID     int64IconUri     stringFormatType  knowledge.DocumentTypeAppID       int64
}type CreateKnowledgeResponse struct {KnowledgeID int64CreatedAtMs int64
}

4.2 领域服务实现特点

知识库领域服务的实现特点:

  • 接口抽象: 通过接口定义清晰的服务边界
  • 类型安全: 使用强类型的请求和响应结构
  • 业务逻辑封装: 将核心业务逻辑封装在领域层
  • 依赖注入: 通过接口依赖其他服务,便于测试和扩展
  • 错误处理: 统一的错误处理机制

4.3 实体定义

文件位置: backend/domain/knowledge/entity/knowledge.go

// Knowledge 知识库实体
type Knowledge struct {ID          int64     `json:"id"`SpaceID     int64     `json:"space_id"`CreatorID   int64     `json:"creator_id"`Name        string    `json:"name"`Description string    `json:"description"`IconURI     string    `json:"icon_uri"`FormatType  int32     `json:"format_type"`Status      int32     `json:"status"`CreatedAt   time.Time `json:"created_at"`UpdatedAt   time.Time `json:"updated_at"`
}// Document 文档实体
type Document struct {ID            int64     `json:"id"`KnowledgeID   int64     `json:"knowledge_id"`Name          string    `json:"name"`FileExtension string    `json:"file_extension"`FileSize      int64     `json:"file_size"`Content       string    `json:"content"`Status        int32     `json:"status"`CreatedAt     time.Time `json:"created_at"`UpdatedAt     time.Time `json:"updated_at"`
}// Slice 分片实体
type Slice struct {ID          int64     `json:"id"`DocumentID  int64     `json:"document_id"`Content     string    `json:"content"`Vector      []float32 `json:"vector"`Position    int64     `json:"position"`WordCount   int32     `json:"word_count"`CreatedAt   time.Time `json:"created_at"`UpdatedAt   time.Time `json:"updated_at"`
}

5. 数据访问层

数据访问层负责知识库相关数据的持久化操作,采用Repository模式和DAO模式相结合的设计,确保数据访问的一致性和可维护性。

5.1 知识库Repository接口定义

文件位置: backend/domain/knowledge/repository/repository.go

知识库数据访问层采用Repository模式,提供统一的数据访问接口:

// Repository 知识库仓储接口
type Repository interface {// 知识库相关操作CreateKnowledge(ctx context.Context, knowledge *entity.Knowledge) (*entity.Knowledge, error)UpdateKnowledge(ctx context.Context, knowledge *entity.Knowledge) errorDeleteKnowledge(ctx context.Context, knowledgeID int64) errorGetKnowledge(ctx context.Context, knowledgeID int64) (*entity.Knowledge, error)ListKnowledge(ctx context.Context, req *ListKnowledgeRequest) ([]*entity.Knowledge, int64, error)// 文档相关操作CreateDocument(ctx context.Context, document *entity.Document) (*entity.Document, error)UpdateDocument(ctx context.Context, document *entity.Document) errorDeleteDocument(ctx context.Context, documentID int64) errorGetDocument(ctx context.Context, documentID int64) (*entity.Document, error)ListDocument(ctx context.Context, req *ListDocumentRequest) ([]*entity.Document, int64, error)// 分片相关操作CreateSlice(ctx context.Context, slice *entity.Slice) (*entity.Slice, error)UpdateSlice(ctx context.Context, slice *entity.Slice) errorDeleteSlice(ctx context.Context, sliceID int64) errorGetSlice(ctx context.Context, sliceID int64) (*entity.Slice, error)ListSlice(ctx context.Context, req *ListSliceRequest) ([]*entity.Slice, int64, error)// 检索相关操作VectorSearch(ctx context.Context, req *VectorSearchRequest) ([]*entity.Slice, error)FullTextSearch(ctx context.Context, req *FullTextSearchRequest) ([]*entity.Slice, error)
}type ListKnowledgeRequest struct {SpaceID    *int64AppID      *int64CreatorID  *int64Query      stringPage       *intPageSize   *intOrder      *stringOrderType  *string
}
创建方法特点
  • 事务支持: 所有写操作都支持事务,确保数据一致性
  • 类型安全: 使用强类型参数,避免运行时错误
  • 错误处理: 详细的错误信息,便于问题定位
  • 批量操作: 支持批量创建,提高性能

5.2 数据访问对象(DAO)

文件位置: backend/domain/knowledge/internal/dal/dao/

// KnowledgeDAO 知识库数据访问对象
type KnowledgeDAO struct {db *gorm.DB
}func (dao *KnowledgeDAO) Create(ctx context.Context, tx *sql.Tx, knowledge *model.Knowledge) (int64, error) {// 1. 生成知识库IDknowledgeID, err := dao.idGenerator.GenerateID()if err != nil {return 0, fmt.Errorf("生成知识库ID失败: %w", err)}// 2. 设置创建时间now := time.Now()knowledge.ID = knowledgeIDknowledge.CreatedAt = nowknowledge.UpdatedAt = now// 3. 执行插入操作result := dao.db.WithContext(ctx).Create(knowledge)if result.Error != nil {return 0, fmt.Errorf("创建知识库失败: %w", result.Error)}return knowledgeID, nil
}// KnowledgeDocumentDAO 知识库文档数据访问对象
type KnowledgeDocumentDAO struct {db *gorm.DB
}func (dao *KnowledgeDocumentDAO) Create(ctx context.Context, tx *sql.Tx, doc *model.KnowledgeDocument) (int64, error) {// 1. 生成文档IDdocID, err := dao.idGenerator.GenerateID()if err != nil {return 0, fmt.Errorf("生成文档ID失败: %w", err)}// 2. 设置文档属性now := time.Now()doc.ID = docIDdoc.CreatedAt = nowdoc.UpdatedAt = now// 3. 执行插入操作result := dao.db.WithContext(ctx).Create(doc)if result.Error != nil {return 0, fmt.Errorf("创建知识库文档失败: %w", result.Error)}return docID, nil
}// KnowledgeDocumentSliceDAO 知识库文档分片数据访问对象
type KnowledgeDocumentSliceDAO struct {db *gorm.DB
}func (dao *KnowledgeDocumentSliceDAO) Create(ctx context.Context, tx *sql.Tx, slice *model.KnowledgeDocumentSlice) (int64, error) {// 1. 生成分片IDsliceID, err := dao.idGenerator.GenerateID()if err != nil {return 0, fmt.Errorf("生成分片ID失败: %w", err)}// 2. 设置分片属性now := time.Now()slice.ID = sliceIDslice.CreatedAt = nowslice.UpdatedAt = now// 3. 执行插入操作result := dao.db.WithContext(ctx).Create(slice)if result.Error != nil {return 0, fmt.Errorf("创建知识库文档分片失败: %w", result.Error)}return sliceID, nil
}
创建操作特点
  • ID生成: 使用分布式ID生成器,确保ID全局唯一
  • 时间戳: 自动设置创建和更新时间
  • 事务处理: 支持事务操作,保证数据一致性
  • 错误处理: 详细的错误信息和日志记录

5.3 完整数据访问流程

知识库创建涉及的数据表:

  1. knowledge: 知识库主表
  2. knowledge_document: 知识库文档表
  3. knowledge_document_slice: 文档分片表
  4. knowledge_config: 知识库配置表

数据访问流程:

  1. 开启数据库事务
  2. 创建知识库主记录
  3. 初始化知识库配置
  4. 提交事务
  5. 发布创建事件

5.4 数据模型定义

文件位置: backend/domain/knowledge/internal/dal/model/

// Knowledge 知识库数据模型
type Knowledge struct {ID          int64     `gorm:"column:id;primaryKey" json:"id"`SpaceID     int64     `gorm:"column:space_id;not null" json:"space_id"`CreatorID   int64     `gorm:"column:creator_id;not null" json:"creator_id"`Name        string    `gorm:"column:name;size:100;not null" json:"name"`Description string    `gorm:"column:description;size:1000" json:"description"`Type        int32     `gorm:"column:type;not null" json:"type"`Config      string    `gorm:"column:config;type:text" json:"config"`Status      int32     `gorm:"column:status;not null" json:"status"`CreatedAt   time.Time `gorm:"column:created_at;not null" json:"created_at"`UpdatedAt   time.Time `gorm:"column:updated_at;not null" json:"updated_at"`
}func (Knowledge) TableName() string {return "knowledge"
}// KnowledgeDocument 知识库文档数据模型
type KnowledgeDocument struct {ID            int64     `gorm:"column:id;primaryKey" json:"id"`KnowledgeID   int64     `gorm:"column:knowledge_id;not null" json:"knowledge_id"`Name          string    `gorm:"column:name;size:255;not null" json:"name"`FileExtension string    `gorm:"column:file_extension;size:10" json:"file_extension"`FileSize      int64     `gorm:"column:file_size" json:"file_size"`Content       string    `gorm:"column:content;type:longtext" json:"content"`Status        int32     `gorm:"column:status;not null" json:"status"`CreatedAt     time.Time `gorm:"column:created_at;not null" json:"created_at"`UpdatedAt     time.Time `gorm:"column:updated_at;not null" json:"updated_at"`
}func (KnowledgeDocument) TableName() string {return "knowledge_document"
}

5.5 查询生成器

文件位置: backend/domain/knowledge/internal/dal/query/

GORM生成的查询接口,提供类型安全的查询方法:

// 知识库查询接口
type IKnowledgeDo interface {gen.SubQueryDebug() IKnowledgeDoWithContext(ctx context.Context) IKnowledgeDoWithResult(fc func(tx gen.Dao)) gen.ResultInfoReplaceDB(db *gorm.DB)ReadDB() IKnowledgeDoWriteDB() IKnowledgeDoAs(alias string) gen.DaoSession(config *gorm.Session) IKnowledgeDoColumns(cols ...field.Expr) gen.ColumnsClauses(conds ...clause.Expression) IKnowledgeDoNot(conds ...gen.Condition) IKnowledgeDoOr(conds ...gen.Condition) IKnowledgeDoSelect(conds ...field.Expr) IKnowledgeDoWhere(conds ...gen.Condition) IKnowledgeDoOrder(conds ...field.Expr) IKnowledgeDoDistinct(cols ...field.Expr) IKnowledgeDoOmit(cols ...field.Expr) IKnowledgeDoJoin(table schema.Tabler, on ...field.Expr) IKnowledgeDoLeftJoin(table schema.Tabler, on ...field.Expr) IKnowledgeDoRightJoin(table schema.Tabler, on ...field.Expr) IKnowledgeDoGroup(cols ...field.Expr) IKnowledgeDoHaving(conds ...gen.Condition) IKnowledgeDoLimit(limit int) IKnowledgeDoOffset(offset int) IKnowledgeDoCount() (count int64, err error)Scopes(funcs ...func(gen.Dao) gen.Dao) IKnowledgeDoUnscoped() IKnowledgeDoCreate(values ...*model.Knowledge) errorCreateInBatches(values []*model.Knowledge, batchSize int) errorSave(values ...*model.Knowledge) errorFirst() (*model.Knowledge, error)Take() (*model.Knowledge, error)Last() (*model.Knowledge, error)Find() ([]*model.Knowledge, error)FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Knowledge, err error)FindInBatches(result *[]*model.Knowledge, batchSize int, fc func(tx gen.Dao, batch int) error) errorPluck(column field.Expr, dest interface{}) errorDelete(...*model.Knowledge) (info gen.ResultInfo, err error)Update(column field.Expr, value interface{}) (info gen.ResultInfo, err error)UpdateSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)Updates(value interface{}) (info gen.ResultInfo, err error)UpdateColumn(column field.Expr, value interface{}) (info gen.ResultInfo, err error)UpdateColumnSimple(columns ...field.AssignExpr) (info gen.ResultInfo, err error)UpdateColumns(value interface{}) (info gen.ResultInfo, err error)UpdateFrom(q gen.SubQuery) gen.DaoAttrs(attrs ...field.AssignExpr) IKnowledgeDoAssign(attrs ...field.AssignExpr) IKnowledgeDoJoins(fields ...field.RelationField) IKnowledgeDoPreload(fields ...field.RelationField) IKnowledgeDoFirstOrInit() (*model.Knowledge, error)FirstOrCreate() (*model.Knowledge, error)FindByPage(offset int, limit int) (result []*model.Knowledge, count int64, err error)ScanByPage(result interface{}, offset int, limit int) (count int64, err error)Scan(result interface{}) (err error)Returning(value interface{}, columns ...string) IKnowledgeDoUnderlyingDB() *gorm.DBschema.Tabler
}

文章转载自:

http://DUZvXJFU.dbrnL.cn
http://YQPzRZpD.dbrnL.cn
http://EQWGcAwt.dbrnL.cn
http://bLjoSFGn.dbrnL.cn
http://0s4bbQoX.dbrnL.cn
http://Fp5ya1a9.dbrnL.cn
http://ma1O6ZcL.dbrnL.cn
http://P5W3xgm9.dbrnL.cn
http://UgreF2ip.dbrnL.cn
http://Au1p9QAF.dbrnL.cn
http://ZBcPEOlW.dbrnL.cn
http://s4sEqHJD.dbrnL.cn
http://XTzpK8Sw.dbrnL.cn
http://kRSMBRSR.dbrnL.cn
http://HNp5jmet.dbrnL.cn
http://uRnoPVcF.dbrnL.cn
http://EcLXR607.dbrnL.cn
http://5LsQuvjw.dbrnL.cn
http://rLHWpFRy.dbrnL.cn
http://Gu0DH89S.dbrnL.cn
http://CzWK9EXz.dbrnL.cn
http://0A4E1cot.dbrnL.cn
http://gvo5Aj4B.dbrnL.cn
http://XPzB4DNk.dbrnL.cn
http://INiIMGWR.dbrnL.cn
http://ab3Ouurc.dbrnL.cn
http://o0E5WPyQ.dbrnL.cn
http://CsuJNIiY.dbrnL.cn
http://caMdYo4L.dbrnL.cn
http://yDV2ARCg.dbrnL.cn
http://www.dtcms.com/a/382850.html

相关文章:

  • React Server Components (RSC) 与 App Router 简介:Next.js 的未来范式
  • 状态机SMACH相关教程介绍与应用案例分析——机器人操作进阶系列之一
  • Grafana与Prometheus实战
  • godot+c#操作godot-sqlite并加解密
  • Scikit-learn 机器学习:构建、训练与评估预测模型
  • React学习教程,从入门到精通,React 组件核心语法知识点详解(类组件体系)(19)
  • Java分布式编程:RMI机制
  • 5-12 WPS JS宏 Range数组规范性测试
  • MySQL 的安装、启动、连接(Windows、macOS 和 Linux)
  • (附源码)基于Spring Boot的宿舍管理系统设计
  • Mac下Python3安装
  • C++数组与字符串:从基础到实战技巧
  • 第13课:分布式Agent系统
  • Docker 容器化部署核心实战——Nginx 服务配置与正反向代理原理解析
  • 【分享】中小学教材课本 PDF 资源获取指南
  • 如何用 Git Hook 和 CI 流水线为 FastAPI 项目保驾护航?
  • 安卓旋转屏幕后如何防止数据丢失-ViewModel入门
  • STM32_05_时钟树
  • 元宇宙与体育产业:沉浸式体验重构体育全链条生态
  • LeetCode 每日一题 966. 元音拼写检查器
  • C++密码锁 2023年CSP-S认证真题 CCF信息学奥赛C++ 中小学提高组 第二轮真题解析
  • Vue3 视频播放器完整指南 – @videojs-player/vue 从入门到精通
  • 零售企业数字化转型的道、法、术:基于开源AI大模型AI智能名片S2B2C商城小程序的战略重构
  • 【编号500】(道路分类)广东路网数据广东路网分类数据(2025年)
  • 【PHP7内核剖析】-1.3 FPM
  • 网络编程之UDP广播与粘包问题
  • h3笔记:polygon
  • Unity 性能优化 之 编辑器创建资源优化( 工作流 | 场景 | 预制体)
  • 《Python Web部署应知应会》No3:Flask网站的性能优化和实时监测深度实战
  • 《嵌入式硬件(十):基于IMX6ULL的按键操作》