You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Neo4j中实现模糊搜索?RAG应用实体多形式匹配

处理实体多形式匹配同一节点

针对实体名称的多种变体(如CY 2023、CY2023、CY 2023、CY23),可以通过以下几种方式实现统一匹配:

1. 标准化存储字段

在节点中新增一个normalized_name字段,提前将所有实体名称转换为统一格式,后续搜索直接匹配该标准化字段。

入库预处理示例:

// 针对CY开头的年份实体,统一标准化为四位年份格式(如CY23→CY2023,CY   2023→CY2023)
MATCH (n:Entity)
WHERE n.name STARTS WITH 'CY'
SET n.normalized_name = 
  let clean_name = replace(n.name, ' ', ''),
  standardized_name = CASE
    WHEN clean_name =~ 'CY\\d{2}' THEN replace(clean_name, 'CY', 'CY20')
    ELSE clean_name
  END

搜索查询示例:

先对用户输入做同样的标准化处理,再匹配normalized_name:

WITH 
  let user_input = $input,
  clean_input = replace(user_input, ' ', ''),
  standardized_input = CASE
    WHEN clean_input =~ 'CY\\d{2}' THEN replace(clean_input, 'CY', 'CY20')
    ELSE clean_input
  END
MATCH (n:Entity)
WHERE n.normalized_name = standardized_input
RETURN n

2. 查询时动态标准化匹配

如果无法修改现有节点结构,可以在查询过程中同时标准化节点名称和用户输入,再进行匹配:

WITH 
  let user_input = $input,
  // 标准化用户输入:去空格+补全年份
  clean_input = replace(trim(user_input), ' ', ''),
  standardized_input = CASE
    WHEN clean_input =~ 'CY\\d{2}' THEN replace(clean_input, 'CY', 'CY20')
    ELSE clean_input
  END
MATCH (n:Entity)
WITH n, standardized_input,
  // 标准化节点名称
  clean_node_name = replace(trim(n.name), ' ', ''),
  standardized_node_name = CASE
    WHEN clean_node_name =~ 'CY\\d{2}' THEN replace(clean_node_name, 'CY', 'CY20')
    ELSE clean_node_name
  END
WHERE standardized_node_name = standardized_input
RETURN n

3. 配置自定义全文索引

创建带有自定义分析器的全文索引,自动处理空格等格式差异,同时可结合同义词扩展处理年份缩写:

// 创建自定义分析器的全文索引,去除所有空格
CREATE FULLTEXT INDEX entity_name_index FOR (n:Entity) ON EACH [n.name]
OPTIONS {
  analyzer: {
    name: 'cy_entity_analyzer',
    tokenizer: 'standard',
    filters: [
      'lowercase',
      'asciifolding',
      { type: 'pattern_replace', pattern: '\\s+', replacement: '' }
    ]
  }
}

扩展查询示例(处理CY23→CY2023):

WITH 
  let user_input = $input,
  clean_input = replace(user_input, ' ', ''),
  // 生成包含缩写和完整形式的查询语句
  query_str = CASE
    WHEN clean_input =~ 'CY\\d{2}' THEN clean_input + ' OR ' + replace(clean_input, 'CY', 'CY20')
    ELSE clean_input
  END
CALL db.index.fulltext.queryNodes('entity_name_index', query_str) YIELD node, score
RETURN node ORDER BY score DESC

Neo4j中的模糊搜索实现

Neo4j支持多种模糊搜索方式,可根据场景选择:

1. 正则表达式匹配

使用=~操作符编写正则规则,灵活匹配字符串模式:

// 匹配包含CY和2023的任意格式名称(忽略中间空格)
MATCH (n:Entity)
WHERE n.name =~ '.*CY\\s*2023.*'
RETURN n

// 匹配以CY开头、年份为两位或四位的实体
MATCH (n:Entity)
WHERE n.name =~ 'CY\\s*(\\d{2}|\\d{4})'
RETURN n

2. 全文索引模糊查询

利用全文索引支持的通配符(*)和模糊匹配(~):

// 前缀匹配:搜索以CY开头的实体
CALL db.index.fulltext.queryNodes('entity_name_index', 'CY*') YIELD node, score
RETURN node

// 模糊匹配:搜索与CY23相似度较高的实体(允许少量字符差异)
CALL db.index.fulltext.queryNodes('entity_name_index', 'CY23~') YIELD node, score
RETURN node ORDER BY score DESC

3. 基于相似度的模糊匹配

使用APOC库的apoc.text.fuzzyMatch函数,通过字符串相似度阈值过滤结果:

// 匹配与输入相似度大于0.8的实体(阈值可调整)
MATCH (n:Entity)
WHERE apoc.text.fuzzyMatch(n.name, $input) > 0.8
RETURN n ORDER BY apoc.text.fuzzyMatch(n.name, $input) DESC

4. 前缀/后缀匹配

使用STARTS WITH、ENDS WITH实现简单的前缀/后缀模糊搜索:

// 搜索名称以CY开头的实体
MATCH (n:Entity)
WHERE n.name STARTS WITH 'CY'
RETURN n

// 搜索名称以2023结尾的实体
MATCH (n:Entity)
WHERE n.name ENDS WITH '2023'
RETURN n

内容的提问来源于stack exchange,提问作者Rajib Deb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 20:24:59