def get_organization_news( topic: Optional[str] = None, organization: Optional[str] = None, country: Optional[str] = None, sentiment: Optional[str] = None,) -> str: # 如果没有预过滤条件,我们可以直接使用向量索引进行搜索 if topic and not organization and not country and not sentiment:return vector_index.similarity_search(topic) # 使用并行运行时(如果可用) base_query = ("CYPHER runtime = parallel parallelRuntimeSupport=all ""MATCH (c:Chunk)<-[:HAS_CHUNK]-(a:Article) WHERE " ) where_queries = [] params = {"k": 5}# 设置要检索的文本块数量
- 接下来,我们动态地向 Cypher 语句添加元数据过滤器 。我们从 Organization 过滤器开始 。
if organization:# 将组织名称映射到数据库中的候选项candidates = get_candidates(organization)if len(candidates) > 1:# 如果候选选项太多,则需要用户进一步明确return f"请明确指出用户指的是以下哪个组织:{candidates}"# 添加一个过滤条件 , 筛选出提及特定组织的 articleswhere_queries.Append(f"EXISTS {{(a)-[:MENTIONS]->(:Organization {{name: $organization}})}}")# 将组织名称作为参数传入params["organization"] = candidates[0]
如果系统识别出用户感兴趣的特定组织,我们会使用 get_candidates 函数将该组织的名称映射到数据库中的候选项 。如果找到多个匹配项,我们会要求用户进一步明确 。如果没有找到多个匹配项,我们会添加一个过滤条件,筛选出提及特定组织的 articles 。为了安全起见,我们使用参数化查询而不是直接拼接查询字符串 。- 随后,我们处理用户可能基于提及的组织的国家进行预过滤的情况 。
if country:# 由于国家名称标准化,不需要额外的映射where_queries.append(f"EXISTS {{(a)-[:MENTIONS]->(:Organization)-[:IN_CITY]->()-[:IN_COUNTRY]->(:Country {{name: $country}})}}")params["country"] = country
由于国家名称通常是标准化的 , 我们不需要将国家名称映射到数据库中的值 , 因为大型语言模型(LLM)已经熟悉大多数国家的名称 。- 随后,我们处理情感元数据的过滤 。
if sentiment:if sentiment == "positive":where_queries.append("a.sentiment > $sentiment")params["sentiment"] = 0.5else:where_queries.append("a.sentiment < $sentiment")params["sentiment"] = -0.5
我们要求 LLM 仅接受正面或负面两种情感输入值,并将这些值映射到适当的过滤器上 。- 对于 topic 参数,我们采取了略有不同的处理方式 , 因为它不用于预过滤,而是用于向量相似性搜索 。
if topic:# 执行向量比较vector_snippet = ("WITH c, a, vector.similarity.cosine(c.embedding,$embedding) AS score ""ORDER BY score DESC LIMIT toInteger($k)")params["embedding"] = embeddings.embed_query(topic)else:# 只返回最新的数据vector_snippet = "WITH c, a ORDER BY a.date DESC LIMIT toInteger($k)"
如果系统识别出用户对新闻中的特定主题感兴趣,我们使用主题输入的文本嵌入来找到最相关的文档 。如果没有识别出特定主题 , 我们简单地返回最新的几篇文章,并避免向量相似性搜索 。- 最后,我们将 Cypher 语句组合起来,并用它来从数据库中检索信息 。
return_snippet = "RETURN '#title ' + a.title + 'n#date ' + toString(a.date) + 'n#text ' + c.text AS output"complete_query = (base_query + " AND ".join(where_queries) + vector_snippet + return_snippet)# 从数据库检索信息data = https://www.isolves.com/it/sjk/bk/2024-04-29/graph.query(complete_query, params)print(f"Cypher: {complete_query}n")# 在打印前安全地移除嵌入params.pop('embedding', None)print(f"参数: {params}")return "###文章: ".join([el["output"] for el in data])
我们通过组合所有查询片段来构建最终的 complete_query 。然后,我们使用动态生成的 Cypher 语句从数据库检索信息并返回结果 。让我们通过一个示例输入来看看生成的 Cypher 语句 。get_organization_news(organizatinotallow='neo4j',sentiment='positive',topic='远程工作')# Cypher: CYPHER runtime = parallel parallelRuntimeSupport=all# MATCH (c:Chunk)<-[:HAS_CHUNK]-(a:Article) WHERE # EXISTS {(a)-[:MENTIONS]->(:Organization {name: $organization})} AND # a.sentiment > $sentiment # WITH c, a, vector.similarity.cosine(c.embedding,$embedding) AS score # ORDER BY score DESC LIMIT toInteger($k) # RETURN '#title ' + a.title + 'n#date ' + toString(a.date) + 'n#text ' + c.text AS output# 参数: {'k': 5, 'organization': 'Neo4j', 'sentiment': 0.5}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 线上MongoDB查询慢,如何通过索引优化直降响应时间?
- 探秘Python神器:eli5模块如何解读机器学习模型的预测结果?
- 为什么MySQL默认使用RR隔离级别?
- 使用 PHP 处理十亿行数据,如何极致提升处理速度?
- MongoDB索引使用总结
- 橄榄树嫁接方法腹接,橄榄树如何种植能高产 橄榄树的种植方法
- 水蒿的功效与作用图片 水蒿和艾草的区别
- 切换微信支付账号怎么设置,手机中的微信支付方式该如何设置
- 花王洗衣机槽清洗剂怎么用 花王洗衣机槽清洗剂如何用
- Excel如何纵向或竖向和,Excel函数怎么横列竖列分别和