Neo4j 在1中组合3个密码查询
我在Spring应用程序中有一个商业模型,其中包含药物。 这背后的理论是,用户有一个全局搜索功能(如谷歌),只有一个输入字段Neo4j 在1中组合3个密码查询,neo4j,cypher,Neo4j,Cypher,我在Spring应用程序中有一个商业模型,其中包含药物。 这背后的理论是,用户有一个全局搜索功能(如谷歌),只有一个输入字段 毒品有个商标名,过期了 药物在物理位置 药物含有物质 (d:药物),(s:槽),(子:物质) d、 tradingName、d.expireDate、sub.substanceName是字符串 s、 数字很长 输入字段中用户搜索的示例 1) Depon(药物的商品名) 2) 扑热息痛(物质名称) 3) 355(他想知道355号槽里有哪种药) 4) 2021-02(他想
- 毒品有个商标名,过期了
- 药物在物理位置
- 药物含有物质
- (d:药物),(s:槽),(子:物质)
- d、 tradingName、d.expireDate、sub.substanceName是字符串
- s、 数字很长
d、 tradingName-d.expire-sub.substanceName-s.number如果您有Neo4j 4,您可以进行联合查询,并通过您的订单对结果进行后期处理
CALL {
MATCH (d:Drug)
WHERE toLower(d.tradingName) CONTAINS toLower({0}) OR toLower(d.expire) CONTAINS toLower({0})
WITH d, datetime(d.expire) as expireDate
RETURN (d)-[]-() AS path, , datetime(d.expire) as expireDate
UNION
MATCH (s:Slot), (d:Drug) WHERE s.number = ({0})
RETURN (d)-[]-(s) AS path, , datetime(d.expire) as expireDate
UNION
MATCH (sub:Substances), (d:Drug)
WHERE toLower(sub.substanceName) CONTAINS toLower({0})
RETURN (sub)-[]-(d) AS path, , datetime(d.expire) as expireDate
} WITH path, expireDate
RETURN path
ORDER BY expireDate
这是一个解释它的链接 如果您有Neo4j 4,您可以进行联合查询,并使用order by对结果进行后期处理
CALL {
MATCH (d:Drug)
WHERE toLower(d.tradingName) CONTAINS toLower({0}) OR toLower(d.expire) CONTAINS toLower({0})
WITH d, datetime(d.expire) as expireDate
RETURN (d)-[]-() AS path, , datetime(d.expire) as expireDate
UNION
MATCH (s:Slot), (d:Drug) WHERE s.number = ({0})
RETURN (d)-[]-(s) AS path, , datetime(d.expire) as expireDate
UNION
MATCH (sub:Substances), (d:Drug)
WHERE toLower(sub.substanceName) CONTAINS toLower({0})
RETURN (sub)-[]-(d) AS path, , datetime(d.expire) as expireDate
} WITH path, expireDate
RETURN path
ORDER BY expireDate
这是一个解释它的链接 您可以通过以下方式组合所有3个查询和订单:
expiredate
(为清晰起见插入空行):
上面的查询通过使用共享正则表达式和=~
运算符对不区分大小写的字符串测试进行了一点改进
此外,查询比原始查询效率更高,因为它不使用导致创建(例如,MATCH(s:Slot)、(d:Drug)
)的MATCH
子句。在执行后续的MATCH
子句之前,在每个“子查询”之间使用COLLECT
,将结果行数减少到1,这也有助于避免笛卡尔积
最后,使用
DISTINCT
选项来消除重复路径,因为理论上多个子查询可能返回相同路径。您可以通过以下方式组合所有3个查询并按过期日期排序(为清楚起见,插入空行):
上面的查询通过使用共享正则表达式和=~
运算符对不区分大小写的字符串测试进行了一点改进
此外,查询比原始查询效率更高,因为它不使用导致创建(例如,MATCH(s:Slot)、(d:Drug)
)的MATCH
子句。在执行后续的MATCH
子句之前,在每个“子查询”之间使用COLLECT
,将结果行数减少到1,这也有助于避免笛卡尔积
最后,使用DISTINCT
选项消除重复路径,由于理论上多个子查询返回相同路径似乎是可能的。很高兴知道这一点存在,但不幸的是,我使用的是3.5.6版很高兴知道这一点存在,但不幸的是,我使用的是3.5.6版非常感谢您的帮助。我在这里看到的唯一问题是在s.number={0}的行上输入应作为数字而不是字符串处理。例如,如果用户键入tralala,输入是文本而不是数字,我如何解决这个问题?该测试直接来自原始查询。为什么要传入无效的参数值?您是说如果值不是数字,则希望忽略匹配
?不确定你想做什么。用户应该能够键入他想要的任何内容。如果他想在插槽50中找到药物,他键入50,插槽编号不是字符串而是数字。这意味着他的输出将粘贴到我的查询中存在的所有{(0)}。但是,如果他键入一个类似“Konstantin”的字符串,其中s.number={0},则此行将抛出一个错误如果WHERE
测试失败,则不会抛出错误。匹配
(如果不是可选
)将不会成功,对于当前数据行,查询的其余部分将中止。如果将我的第二个匹配
替换为可选匹配
,则查询的其余部分将不会中止——这可能满足您的需要?Neo.ClientError.Statement.SyntaxError:VariableKonstantinos
未定义(第6行,第18列(偏移量:186))“其中s.number=Konstantinos”这是我得到的错误,即使我用可选的匹配项替换它。如果不是这样的话,查询需要一个纯数字。有一个错误。非常感谢您的帮助。我在这里看到的唯一问题是,在s.Number={0}行中,输入应该作为数字而不是字符串处理。例如,如果用户键入tralala,输入是文本而不是数字,我如何解决这个问题?该测试直接来自原始查询。为什么要传入无效的参数值?您是说如果值不是数字,则希望忽略匹配
?不确定你想做什么。用户应该能够键入他想要的任何内容。如果他想在插槽50中找到药物,他键入50,插槽编号不是字符串而是数字。这意味着他的输出将粘贴到我的查询中存在的所有{(0)}。但是,如果他键入一个类似“Konstantin”的字符串,其中s.number={0},则此行将抛出一个错误如果WHERE
测试失败,则不会抛出错误。匹配
(如果不是可选
)将不会成功,查询的其余部分将被中止
MATCH (sub:Substances), (d:Drug)
WHERE toLower(sub.substanceName) CONTAINS toLower({0})
RETURN (sub)-[]-(d)
CALL {
MATCH (d:Drug)
WHERE toLower(d.tradingName) CONTAINS toLower({0}) OR toLower(d.expire) CONTAINS toLower({0})
WITH d, datetime(d.expire) as expireDate
RETURN (d)-[]-() AS path, , datetime(d.expire) as expireDate
UNION
MATCH (s:Slot), (d:Drug) WHERE s.number = ({0})
RETURN (d)-[]-(s) AS path, , datetime(d.expire) as expireDate
UNION
MATCH (sub:Substances), (d:Drug)
WHERE toLower(sub.substanceName) CONTAINS toLower({0})
RETURN (sub)-[]-(d) AS path, , datetime(d.expire) as expireDate
} WITH path, expireDate
RETURN path
ORDER BY expireDate
WITH '(?i).*' + {0} + '.*' AS regex
MATCH p1=(d:Drug)--()
WHERE d.tradingName =~ regex OR d.expire =~ regex
WITH regex, COLLECT(p1) AS ps
MATCH p2=(:Drug)--(s:Slot)
WHERE s.number = {0}
WITH regex, ps+COLLECT(p2) AS ps
MATCH p3=(:Drug)--(sub:Substances)
WHERE sub.substanceName =~ regex
WITH ps+COLLECT(p3) AS ps
UNWIND ps AS p
RETURN DISTINCT p
ORDER BY NODES(p)[0].expireDate;