我正在尝试用 Neo4J 中的 Cypher 解决一个问题,我需要找到具有最佳气味和外观组合的
BEER_STYLE
。关系如下:
(:REVIEW)<-[:REVIEWED]-(:BEER)-[:HAS_STYLE]->(:BEER_STYLE)
一种啤酒有时会有多个评论,评论节点有两个令人感兴趣的属性:外观和气味。有时这 2 种可能是
NaN
,我必须找到具有这 2 种最佳组合的风格(我认为这可能是平均值的平均值)。
我尝试编写一个总体想法,并要求 ChatGPT 进行打磨,直到它起作用,但我不太有信心,想在这里问。 这是我得到的代码,有人可以帮助/纠正我改进它吗?
MATCH (s:STYLE)<-[h:HAS_STYLE]-(b:BEERS)-[rev:REVIEWED]->(r:REVIEWS)
WITH s,
CASE WHEN r.look <> 'NaN' THEN toFloat(r.look) ELSE null END AS look,
CASE WHEN r.smell <> 'NaN' THEN toFloat(r.smell) ELSE null END AS smell
WITH s, AVG(look) AS avg_look, AVG(smell) AS avg_smell
WITH s, avg_look, avg_smell, ((avg_look + avg_smell) / 2) AS total
RETURN s AS STYLE, MAX(total) AS Final_Class
ORDER BY Final_Class DESC
LIMIT 2
如果
look
和 smell
值不需要存储为字符串,您应该首先将它们更改为浮点数,以避免每次使用这些属性时都必须进行转换:
MATCH (r:REVIEWS)
SET r.look = CASE WHEN r.look <> 'NaN' THEN toFloat(r.look) END
SET r.smell = CASE WHEN r.smell <> 'NaN' THEN toFloat(r.smell) END
备注:
NULL
是 CASE
的默认值,因此不需要在 ELSE
中指定。NULL
分配给属性时,该属性将被删除。在一次性查询修复属性值之后,您的用例可以简化为:
MATCH (s:STYLE)<-[:HAS_STYLE]-(:BEERS)-[:REVIEWED]->(r:REVIEWS)
RETURN s AS STYLE, ((AVG(r.look) + AVG(r.smell)) / 2) AS Final_Class
ORDER BY Final_Class DESC
LIMIT 2
备注:
您的原始查询不需要对每个
MAX
的total
值调用s
,因为在以下子句中使用聚合函数AVG
只会创建一个avg_look
并且每个 avg_smell
的 s
值,导致每个 total
仅产生一个 s
:
WITH s, AVG(look) AS avg_look, AVG(smell) AS avg_smell