Spring应用中合并3条Cypher查询实现药品全局搜索
合并Cypher查询实现全局药品搜索
我来帮你把这三个查询合并成一条,同时满足全局搜索需求并按过期时间排序。这里是最终的Cypher语句,后面我会拆解每个部分的作用:
MATCH (d:Drug) OPTIONAL MATCH (d)-[]-(s:Slot) OPTIONAL MATCH (d)-[]-(sub:Substances) WHERE toLower(d.tradingName) CONTAINS toLower($searchTerm) OR toLower(d.expireDate) CONTAINS toLower($searchTerm) OR (s.number IS NOT NULL AND s.number = toInteger($searchTerm)) OR (sub.substanceName IS NOT NULL AND toLower(sub.substanceName) CONTAINS toLower($searchTerm)) WITH d, collect(DISTINCT s) as slots, collect(DISTINCT sub) as substances, datetime(d.expireDate) as expireDate ORDER BY expireDate UNWIND slots as s UNWIND substances as sub RETURN d.tradingName, d.expireDate, sub.substanceName, s.number
关键细节解释:
- 关联节点:先用
MATCH (d:Drug)定位所有药品,再通过OPTIONAL MATCH关联它的槽位和成分。用OPTIONAL是为了避免过滤掉暂时没有槽位或成分的药品(如果你的业务中药品必须关联这两者,可以换成普通MATCH)。 - 多条件搜索:
WHERE子句覆盖了你需要的所有搜索场景:- 匹配药品商品名(忽略大小写,兼容不同输入格式)
- 匹配过期时间(支持模糊匹配,比如输入
2021-02能命中2021-02-15这类完整日期) - 匹配槽位编号:用
toInteger($searchTerm)把输入的字符串转成Long类型,和槽位的number属性匹配,同时加s.number IS NOT NULL避免空值干扰 - 匹配成分名(同样忽略大小写,提升搜索容错性)
- 去重与排序:用
collect(DISTINCT ...)收集每个药品对应的所有槽位和成分,避免出现重复行;然后基于datetime(d.expireDate)排序,确保结果按过期时间有序展示。 - 展开结果:最后用
UNWIND把收集的槽位和成分展开,让每个药品的每个槽位+成分组合都返回一行,方便前端直接拼接成你要的d.tradingName - d.expireDate - sub.substanceName - s.number格式。
优化建议:
如果你的数据模型中,药品和槽位、成分的关系是明确的(比如药品存放在槽位是STORED_IN关系,包含成分是CONTAINS关系),可以把OPTIONAL MATCH里的[]换成具体的关系类型,比如:
OPTIONAL MATCH (d)-[:STORED_IN]->(s:Slot) OPTIONAL MATCH (d)-[:CONTAINS]->(sub:Substances)
这样查询会更高效,因为不会匹配无关的关系。
内容的提问来源于stack exchange,提问作者Tsolakidis Konstantinos
相关产品推荐
相关产品推荐

