Neo4j 在1中组合3个密码查询

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(他想

我在Spring应用程序中有一个商业模型,其中包含药物。 这背后的理论是,用户有一个全局搜索功能(如谷歌),只有一个输入字段

  • 毒品有个商标名,过期了

  • 药物在物理位置

  • 药物含有物质

  • (d:药物),(s:槽),(子:物质)

  • d、 tradingName、d.expireDate、sub.substanceName是字符串

  • s、 数字很长

输入字段中用户搜索的示例

1) Depon(药物的商品名)

2) 扑热息痛(物质名称)

3) 355(他想知道355号槽里有哪种药)

4) 2021-02(他想知道哪些药物在2021年2月到期)

关键是,无论用户搜索什么,输出都应该是相同的。一份药品清单及其所有信息,但我在前端处理

现在我有3个问题

(一)

这是一个完美的工作,也排序输出,但它没有搜索槽和实质

(二)

(三)

如何可能将所有这些查询合并到一个查询,并最终输出订购的过期日期药物及其与插槽和物质的关系

最终的输出应该是这样的


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:Variable
Konstantinos
未定义(第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;