Neo4j基于权重关系构建推荐系统的Cypher查询问题求解
Neo4j 基于规格权重的商品推荐Cypher实现
原有语句问题
你写的语句核心问题是MERGE (user)-[:WEIGHT{score:0}]->(a)这一步:MERGE会把关系上携带的所有属性作为匹配判定条件,只要用户和规格之间的WEIGHT关系score不等于0,MERGE就会判定关系不存在,重复创建新的WEIGHT关系,完全不符合分值累加的需求。
正确语句实现
按照两种用户行为分别写对应语句即可,核心逻辑是MERGE关系时不携带动态变化的score属性,匹配到关系后再分支处理初始化/累加逻辑。
收藏行为(对应规格权重+20)
MATCH (user:Users {m_id: $user_id}) MATCH (product:Products {m_id: $product_id})-[:HAS]->(spec:Specifications) // 匹配/创建用户对商品的收藏关系 MERGE (user)-[:FAVORITE]->(product) // 仅按节点匹配WEIGHT关系,不把score作为匹配条件 MERGE (user)-[weight_rel:WEIGHT]->(spec) // 新建关系时直接初始化分值为20,已存在则累加20 ON CREATE SET weight_rel.score = 20 ON MATCH SET weight_rel.score = weight_rel.score + 20
语句中
$user_id、$product_id是参数占位符,实际执行时传入对应用户、商品的m_id值即可。
浏览行为(对应规格权重+10)
MATCH (user:Users {m_id: $user_id}) MATCH (product:Products {m_id: $product_id})-[:HAS]->(spec:Specifications) // 匹配/创建用户对商品的浏览关系 MERGE (user)-[:SEEN]->(product) // 仅按节点匹配WEIGHT关系 MERGE (user)-[weight_rel:WEIGHT]->(spec) // 新建关系时初始化分值为10,已存在则累加10 ON CREATE SET weight_rel.score = 10 ON MATCH SET weight_rel.score = weight_rel.score + 10
注意事项
- 不要在MERGE携带动态属性的关系时,把动态属性写入MERGE的匹配条件,否则必然出现重复创建关系的问题。
- 如果需要做行为幂等(比如用户取消收藏后再次收藏、短时间内重复浏览同一个商品不重复加分),可以在
FAVORITE/SEEN关系上增加唯一标识属性(比如行为唯一ID、行为时间戳),MERGE行为关系时带上这个唯一属性,就能避免重复触发权重累加。 - 后续生成推荐结果时,直接匹配用户关联的
:WEIGHT关系,按score倒序取高权重规格,再匹配关联了这些规格、且用户未产生过seen/favorite关系的商品返回即可。
内容的提问来源于stack exchange,提问作者hosein morshedy
相关产品推荐
相关产品推荐

