dify实现分析-rag-关键词索引的实现
- 电脑硬件
- 2025-08-28 03:09:01

概述
在dify中有两种构建索引的方式,一种是经济型,另一种是高质量索引(通过向量数据库来实现)。其中经济型就是关键词索引,通过构建关键词索引来定位查询的文本块,而关键词索引的构建是通过Jieba这个库来完成的。
Jieba(“结巴”)是一个强大的中文分词和关键词提取工具库。在dify中,Jieba类作为一个基于关键词的文档检索系统的核心实现。
本文介绍关键词索引的构建类Jieba类的实现,包括:文本的索引的添加,修改等操作。
Jieba类的构成 #mermaid-svg-zqD0wgowzKbjXUmr {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-zqD0wgowzKbjXUmr .error-icon{fill:#552222;}#mermaid-svg-zqD0wgowzKbjXUmr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zqD0wgowzKbjXUmr .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-zqD0wgowzKbjXUmr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zqD0wgowzKbjXUmr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zqD0wgowzKbjXUmr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zqD0wgowzKbjXUmr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zqD0wgowzKbjXUmr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zqD0wgowzKbjXUmr .marker.cross{stroke:#333333;}#mermaid-svg-zqD0wgowzKbjXUmr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zqD0wgowzKbjXUmr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zqD0wgowzKbjXUmr .cluster-label text{fill:#333;}#mermaid-svg-zqD0wgowzKbjXUmr .cluster-label span{color:#333;}#mermaid-svg-zqD0wgowzKbjXUmr .label text,#mermaid-svg-zqD0wgowzKbjXUmr span{fill:#333;color:#333;}#mermaid-svg-zqD0wgowzKbjXUmr .node rect,#mermaid-svg-zqD0wgowzKbjXUmr .node circle,#mermaid-svg-zqD0wgowzKbjXUmr .node ellipse,#mermaid-svg-zqD0wgowzKbjXUmr .node polygon,#mermaid-svg-zqD0wgowzKbjXUmr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zqD0wgowzKbjXUmr .node .label{text-align:center;}#mermaid-svg-zqD0wgowzKbjXUmr .node.clickable{cursor:pointer;}#mermaid-svg-zqD0wgowzKbjXUmr .arrowheadPath{fill:#333333;}#mermaid-svg-zqD0wgowzKbjXUmr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zqD0wgowzKbjXUmr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zqD0wgowzKbjXUmr .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-zqD0wgowzKbjXUmr .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-zqD0wgowzKbjXUmr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zqD0wgowzKbjXUmr .cluster text{fill:#333;}#mermaid-svg-zqD0wgowzKbjXUmr .cluster span{color:#333;}#mermaid-svg-zqD0wgowzKbjXUmr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zqD0wgowzKbjXUmr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Jieba类 基础功能 数据管理 搜索功能 关键词提取 分词处理 关键词表管理 存储策略 关键词搜索 文档检索 关键词索引创建 总体实现逻辑关键词索引创建在create函数中实现,该函数的声明如下:
def create(self, texts: list[Document], **kwargs) -> BaseKeyword:该函数的主要逻辑如下:
#mermaid-svg-z9ojsITXASocOp4u {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-z9ojsITXASocOp4u .error-icon{fill:#552222;}#mermaid-svg-z9ojsITXASocOp4u .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-z9ojsITXASocOp4u .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-z9ojsITXASocOp4u .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-z9ojsITXASocOp4u .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-z9ojsITXASocOp4u .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-z9ojsITXASocOp4u .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-z9ojsITXASocOp4u .marker{fill:#333333;stroke:#333333;}#mermaid-svg-z9ojsITXASocOp4u .marker.cross{stroke:#333333;}#mermaid-svg-z9ojsITXASocOp4u svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-z9ojsITXASocOp4u .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-z9ojsITXASocOp4u .cluster-label text{fill:#333;}#mermaid-svg-z9ojsITXASocOp4u .cluster-label span{color:#333;}#mermaid-svg-z9ojsITXASocOp4u .label text,#mermaid-svg-z9ojsITXASocOp4u span{fill:#333;color:#333;}#mermaid-svg-z9ojsITXASocOp4u .node rect,#mermaid-svg-z9ojsITXASocOp4u .node circle,#mermaid-svg-z9ojsITXASocOp4u .node ellipse,#mermaid-svg-z9ojsITXASocOp4u .node polygon,#mermaid-svg-z9ojsITXASocOp4u .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-z9ojsITXASocOp4u .node .label{text-align:center;}#mermaid-svg-z9ojsITXASocOp4u .node.clickable{cursor:pointer;}#mermaid-svg-z9ojsITXASocOp4u .arrowheadPath{fill:#333333;}#mermaid-svg-z9ojsITXASocOp4u .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-z9ojsITXASocOp4u .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-z9ojsITXASocOp4u .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-z9ojsITXASocOp4u .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-z9ojsITXASocOp4u .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-z9ojsITXASocOp4u .cluster text{fill:#333;}#mermaid-svg-z9ojsITXASocOp4u .cluster span{color:#333;}#mermaid-svg-z9ojsITXASocOp4u div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-z9ojsITXASocOp4u :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 开始创建关键词索引 获取Redis分布式锁 检查关键词表是否存在,若不存在,创建关键词表:dataset_keyword_tables 遍历文件分块列表: Document对象列表 关键词提取: extract_keywords 更新段落关键词 更新关键词表: 把关键词保存到字典中 保存关键词表: 保存关键词表到数据库或文件系统 返回实例 关键词提取:extract_keywords关键词提取主要完成:从文本中提取关键词,支持停用词过滤和子词提取。extract_keywords函数的声明如下:
def extract_keywords(self, text: str, max_keywords_per_chunk: Optional[int] = 10) -> set[str]:该函数的处理流程如下:
#mermaid-svg-esLK6VIEgYoGXXJi {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-esLK6VIEgYoGXXJi .error-icon{fill:#552222;}#mermaid-svg-esLK6VIEgYoGXXJi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-esLK6VIEgYoGXXJi .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-esLK6VIEgYoGXXJi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-esLK6VIEgYoGXXJi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-esLK6VIEgYoGXXJi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-esLK6VIEgYoGXXJi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-esLK6VIEgYoGXXJi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-esLK6VIEgYoGXXJi .marker.cross{stroke:#333333;}#mermaid-svg-esLK6VIEgYoGXXJi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-esLK6VIEgYoGXXJi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-esLK6VIEgYoGXXJi .cluster-label text{fill:#333;}#mermaid-svg-esLK6VIEgYoGXXJi .cluster-label span{color:#333;}#mermaid-svg-esLK6VIEgYoGXXJi .label text,#mermaid-svg-esLK6VIEgYoGXXJi span{fill:#333;color:#333;}#mermaid-svg-esLK6VIEgYoGXXJi .node rect,#mermaid-svg-esLK6VIEgYoGXXJi .node circle,#mermaid-svg-esLK6VIEgYoGXXJi .node ellipse,#mermaid-svg-esLK6VIEgYoGXXJi .node polygon,#mermaid-svg-esLK6VIEgYoGXXJi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-esLK6VIEgYoGXXJi .node .label{text-align:center;}#mermaid-svg-esLK6VIEgYoGXXJi .node.clickable{cursor:pointer;}#mermaid-svg-esLK6VIEgYoGXXJi .arrowheadPath{fill:#333333;}#mermaid-svg-esLK6VIEgYoGXXJi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-esLK6VIEgYoGXXJi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-esLK6VIEgYoGXXJi .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-esLK6VIEgYoGXXJi .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-esLK6VIEgYoGXXJi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-esLK6VIEgYoGXXJi .cluster text{fill:#333;}#mermaid-svg-esLK6VIEgYoGXXJi .cluster span{color:#333;}#mermaid-svg-esLK6VIEgYoGXXJi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-esLK6VIEgYoGXXJi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入文本 TFIDF关键词提取 子词拆分 停用词过滤 返回关键词集合 def extract_keywords(self, text: str, max_keywords_per_chunk: Optional[int] = 10) -> set[str]: """Extract keywords with JIEBA tfidf.""" # 1. 使用TFIDF算法提取关键词 keywords = jieba.analyse.extract_tags( sentence=text, topK=max_keywords_per_chunk, # 默认最多10个关键词 ) # 2. 扩展子词并过滤停用词 return set(self._expand_tokens_with_subtokens(keywords)) def _expand_tokens_with_subtokens(self, tokens: set[str]) -> set[str]: """获取tokens的子词,并过滤停用词""" results = set() for token in tokens: # 1. 添加原始token results.add(token) # 2. 使用正则提取子词 sub_tokens = re.findall(r"\w+", token) # 3. 如果存在多个子词 if len(sub_tokens) > 1: # 过滤停用词并添加到结果集 results.update({w for w in sub_tokens if w not in list(STOPWORDS)}) return results 关键词存储关键词存储的函数声明如下:
def _save_dataset_keyword_table(self, keyword_table):其中处理完成的关键词,都已经保存到dataset_keyword_tables字典中了。
#mermaid-svg-eMEVZDZL9873oGEf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-eMEVZDZL9873oGEf .error-icon{fill:#552222;}#mermaid-svg-eMEVZDZL9873oGEf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eMEVZDZL9873oGEf .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-eMEVZDZL9873oGEf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eMEVZDZL9873oGEf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eMEVZDZL9873oGEf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eMEVZDZL9873oGEf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eMEVZDZL9873oGEf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eMEVZDZL9873oGEf .marker.cross{stroke:#333333;}#mermaid-svg-eMEVZDZL9873oGEf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eMEVZDZL9873oGEf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-eMEVZDZL9873oGEf .cluster-label text{fill:#333;}#mermaid-svg-eMEVZDZL9873oGEf .cluster-label span{color:#333;}#mermaid-svg-eMEVZDZL9873oGEf .label text,#mermaid-svg-eMEVZDZL9873oGEf span{fill:#333;color:#333;}#mermaid-svg-eMEVZDZL9873oGEf .node rect,#mermaid-svg-eMEVZDZL9873oGEf .node circle,#mermaid-svg-eMEVZDZL9873oGEf .node ellipse,#mermaid-svg-eMEVZDZL9873oGEf .node polygon,#mermaid-svg-eMEVZDZL9873oGEf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-eMEVZDZL9873oGEf .node .label{text-align:center;}#mermaid-svg-eMEVZDZL9873oGEf .node.clickable{cursor:pointer;}#mermaid-svg-eMEVZDZL9873oGEf .arrowheadPath{fill:#333333;}#mermaid-svg-eMEVZDZL9873oGEf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-eMEVZDZL9873oGEf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-eMEVZDZL9873oGEf .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-eMEVZDZL9873oGEf .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-eMEVZDZL9873oGEf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-eMEVZDZL9873oGEf .cluster text{fill:#333;}#mermaid-svg-eMEVZDZL9873oGEf .cluster span{color:#333;}#mermaid-svg-eMEVZDZL9873oGEf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-eMEVZDZL9873oGEf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 接收关键词表 构建元数据字典 判断存储类型 数据库存储: database 文件存储: file JSON序列化 构建文件路径 检查文件是否存在: 若存在删除之 保存文件该函数的详细实现如下:
# 这段代码的主要功能是将一个关键词表 (dataset_keyword_tables) 保存到数据库或文件中,具体取决于数据源类型。 def _save_dataset_keyword_table(self, keyword_table): # 创建数据字典,保存元数据信息 keyword_table_dict = { "__type__": "keyword_table", "__data__": {"index_id": self.dataset.id, "summary": None, "table": keyword_table}, } # 记录数据集的数据来源类型 dataset_keyword_table = self.dataset.dataset_keyword_table keyword_data_source_type = dataset_keyword_table.data_source_type # 数据源是数据库,则将字典编码为 JSON 字符串,并更新数据库中的 keyword_table 字段。然后提交事务。 if keyword_data_source_type == "database": dataset_keyword_table.keyword_table = json.dumps(keyword_table_dict, cls=SetEncoder) db.session mit() else: # 来源是文件,则构建一个文件键(路径),检查文件是否存在,如果存在则删除 file_key = "keyword_files/" + self.dataset.tenant_id + "/" + self.dataset.id + ".txt" if storage.exists(file_key): storage.delete(file_key) # 最后将字典编码为 JSON 并保存到指定的文件路径。 storage.save(file_key, json.dumps(keyword_table_dict, cls=SetEncoder).encode("utf-8")) class SetEncoder(json.JSONEncoder): """自定义JSON编码器,处理set类型""" def default(self, obj): if isinstance(obj, set): return list(obj) # 将set转换为list return super().default(obj) 关键词查询 #mermaid-svg-Qa5jpQTNGFRlR0h2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .error-icon{fill:#552222;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .marker.cross{stroke:#333333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .cluster-label text{fill:#333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .cluster-label span{color:#333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .label text,#mermaid-svg-Qa5jpQTNGFRlR0h2 span{fill:#333;color:#333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .node rect,#mermaid-svg-Qa5jpQTNGFRlR0h2 .node circle,#mermaid-svg-Qa5jpQTNGFRlR0h2 .node ellipse,#mermaid-svg-Qa5jpQTNGFRlR0h2 .node polygon,#mermaid-svg-Qa5jpQTNGFRlR0h2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .node .label{text-align:center;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .node.clickable{cursor:pointer;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .arrowheadPath{fill:#333333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .cluster text{fill:#333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 .cluster span{color:#333;}#mermaid-svg-Qa5jpQTNGFRlR0h2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Qa5jpQTNGFRlR0h2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 获取关键词表名,从表中查询对应数据集的关键词字典 获取top-k参数 提取查询字符串中的关键词,根据查询关键词在文档切片关键词中进行查询,并对结果排序 按排序切片索引id从数据库表中查询文档内容 构建Document对象 返回Document对象列表search函数的详细实现分析:
def search(self, query: str, **kwargs: Any) -> list[Document]: # 从dataset_keyword_tables表中获取对应数据集的数据分块记录字典 keyword_table = self._get_dataset_keyword_table() k = kwargs.get("top_k", 4) # (1)使用Jieba对用户输入的查询字符串进行关键词提取 # (2)然后从刚才查询出来的关键词字典中,查询出与查询字符串中关键词匹配的文本索引id sorted_chunk_indices = self._retrieve_ids_by_query(keyword_table, query, k) documents = [] # 根据文本块索引id,从数据库中查询出对应的文本块内容 for chunk_index in sorted_chunk_indices: segment = ( db.session.query(DocumentSegment) .filter(DocumentSegment.dataset_id == self.dataset.id, DocumentSegment.index_node_id == chunk_index) .first() ) # 以Document对象结构来返回结果 if segment: documents.append( Document( page_content=segment.content, metadata={ "doc_id": chunk_index, "doc_hash": segment.index_node_hash, "document_id": segment.document_id, "dataset_id": segment.dataset_id, }, ) ) return documents 小结说明,分析到这里,我们基本上就了解了关键词查询的基本原理:对用户查询字符串进行分词处理(通过Jieba库),根据分词结果在对应数据集中查询对应分词,然后获取该分词对应的文本和文本块。
可见,关键词索引主要是依赖对文本进行分词,然后通过分词来进行匹配,从而找到对应文本块的数据。这种方式并没有从语义角度去理解文本,本质上是通过分词得到的关键词进行匹配的方式来找到对应文本块。与通过语义的方式来查找文本,这种方式会存在一定的局限性。
关键词添加和删除关键词的添加和删除都是要先从数据表或文件中把该数据集原有关键词读取到一个字典中,然后对该字典中的关键词进行添加或删除操作,然后再把数据写回数据表或文件。
(1)先查询数据集对应的关键词表(或文件)的数据,并以字典的方式返回
(2)在字典中添加对应关键词
(3)把添加完关键词的字典再写回关键词存储表或文件中
关键词的删除和关键词添加步骤类似,只是在第二步会从获取到的字段中把关键词删除,然后再写回数据表或文件中。
总结关键词索引方式不需要其他额外的存储组件就可以完成索引的构建,成本相对比较低,比较经济实惠。但该方式是通过分词和关键词匹配方式来构建的文本块查询,比起通过向量和语义匹配的方式,有一定的局限性,选择那种方式,需要根据具体的场景来确定。
dify实现分析-rag-关键词索引的实现由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“dify实现分析-rag-关键词索引的实现”