Neo4j:试图在不同的数据块中找到遵循特定单词或模式的字符串,但无法找出正确的查询来实现这一目标

camsedfj  于 2023-10-18  发布在  其他
关注(0)|答案(3)|浏览(111)

我试图找到数据库中特定类型节点的数据中包含的特定属性的值。我想我需要做的是匹配一个特定的字符串,它总是在这些值之前,然后从数据块中提取这些值。
所以,我试着这样做:

MATCH 
    (c:course)-[:PARENT_OF*]->(n:item) 
WHERE 
    n.data CONTAINS "some string"       
RETURN 
    {the text immediately following "some string"}

抱歉,说得有点含糊...我不确定我能因为各种原因而变得具体。
基本上,我想找到-假设数据块是'你好,我的名字是莎莉,我现在真的可以去一些薯条' -数据块中的名字,所以,莎莉。此外,如果数据中还有另一个名字,它遵循模式“我的名字是_",我也想找到它。这有道理吗
在Neo4j中可以做到这一点吗?
我知道有一种方法可以返回包含在节点中的/data的全部内容,我现在也知道有一种方法可以返回该节点中的一部分内容,但这就是我卡住的地方,因为我只能从上面的稀疏示例中获得- Neo4j只返回我提供的字符串的一些子字符串,而不是它后面的任何东西。
我试过

...
RETURN 
    substring(n.data,100,500)

查找数据的一部分,从数据中的第100个字符开始,到第500个字符为止。
我也试过

...
RETURN 
    right('hello', 3)

找到子字符串中的一部分引号('hello'),特别是从该子字符串中的第3个字符开始(这样我就得到了像'llo'这样的结果)。
我想我不知道如何在Neo4j中查询一个模式,这样它就可以给予我遵循这个模式的内容。

im9ewurl

im9ewurl1#

让我们来看看Hakan的回答。如果你说在同一个字符串中可能有多个名字,例如。“Hello,my name is John and my姐妹篇name is Jane and we both likes fries”,如果您想提取键“name is“之后的所有名称,则可以使用此方法

WITH "name is " AS key 
MATCH (n:item) WHERE n.data CONTAINS key 
WITH key, n.data AS text, apoc.text.indexesOf(n.data, key) AS indexes 
UNWIND indexes AS index 
WITH key, text, index+size(key) AS nameindex 
RETURN substring(text, nameindex, apoc.text.indexOf(text, " ", nameindex)-nameindex)

一个警告是,如果文本末尾有一个名字,这个版本就不起作用了(因为它需要一个空格来跟随名字)。我也需要多想想怎么解决这个案子。
编辑:
下面这个版本也解决了这种特殊情况(一个名字出现在字符串的末尾,后面没有空格):

WITH "name is " AS key 
MATCH (n:Person) WHERE n.data CONTAINS key 
WITH key, n.data AS text, apoc.text.indexesOf(n.data, key) AS indexes 
UNWIND indexes AS index 
WITH key, text, index+size(key) AS nameindex, apoc.text.indexOf(text, " ", index+size(key)) AS endindex
RETURN
CASE endindex
WHEN -1 THEN substring(text, nameindex)
ELSE substring(text, nameindex, endindex-nameindex)
END

顺便说一下,这需要你安装“APOC Core”库(它默认安装在Aura上,但如果你运行自己的示例,你需要安装它。只需将文件apoc-5.X.X-core.jar从labs文件夹移动到plugins文件夹,然后重新启动即可。

rqcrx0a6

rqcrx0a62#

您可以利用核心APOC函数apoc.text.regexGroups来使用正则表达式,该正则表达式不区分大小写进行搜索,并忽略名称周围的非字母数字字符。举例来说:

UNWIND [
    "Hello my name is Sally and I really could go for some fries right now. Did I mention that my name is Sally?",
    "My name is Waldo but sometimes I say my name is Charlie, and sometimes I say my name is **Fido**. Arf!"
] AS s

UNWIND apoc.text.regexGroups(s, '(?i)my name is \W*(\w+)') AS group
RETURN s, apoc.coll.flatten(COLLECT(TAIL(group))) AS names

返回:

╒═══════════════════════════════════════╤════════════════════════════╕
│s                                      │names                       │
╞═══════════════════════════════════════╪════════════════════════════╡
│"Hello my name is Sally and I really co│["Sally", "Sally"]          │
│uld go for some fries right now. Did I │                            │
│mention that my name is Sally?"        │                            │
├───────────────────────────────────────┼────────────────────────────┤
│"My name is Waldo but sometimes I say m│["Waldo", "Charlie", "Fido"]│
│y name is Charlie, and sometimes I say │                            │
│my name is **Fido**. Arf!"             │                            │
└───────────────────────────────────────┴────────────────────────────┘
8fq7wneg

8fq7wneg3#

如果你希望文本以你的文本片段开始,你可以这样做:

UNWIND [
    "Hello my name is Sally and I really could go for some fries right now",
    "Hello my name is Ben and I really could go for a burger right now"
] AS text
WITH text, "Hello my name is" as q
WHERE text starts with q
RETURN trim(right(text, size(text)-size(q)))

如果你只希望文本包含文本片段,你需要使用apoc.text.indexOf:

UNWIND [
    "Hello my name is Sally and I really could go for some fries right now",
    "Hello my name is Ben and I really could go for a burger right now"
] AS text
WITH text, "my name is" as q
WHERE text contains q
RETURN trim(right(text, size(text)-apoc.text.indexOf(text,q)-size(q)))

相关问题