#neo4j #cypher #collect
Вопрос:
В Neo4j у меня есть набор графиков, состоящий из начальных терминов и синонимов, добавляемых к этим начальным терминам через отношения [:SYNONYM_OF]
. Я пишу функцию, в которой любой узел, содержащий слово, соответствующее синониму определенного начального термина, возвращается вместе с любыми соответствующими перечисленными синонимами. Мой текущий запрос показан ниже:
MATCH (b)-[*]->(z)-[*]->(n),
(syn)<-[r]->(seed:Seed_Term {name: "valuation"})
WHERE (
(
n.name CONTAINS toLower(syn.name)
OR n.content CONTAINS toLower(syn.name)
)
OR (
n.name CONTAINS toUpper(syn.name)
OR n.content CONTAINS toUpper(syn.name)
)
)
AND (b:Label)
AND (n:Title OR n:Text OR n:Column OR n:RowName OR n:Cell)
AND (z:Pdf)
RETURN n.name AS node,
syn.name AS synonym_found,
seed.name AS seed_term,
b.labelName AS company,
z.year AS year,
r AS rel_type
LIMIT 1000
Единственная проблема с этим заключается в том, что если найдено три разных синонима, он возвращает строку, содержащую содержимое (узел) три раза, причем синоним_поиск каждый раз отличается. Я знаю , что вместо этого я должен делать collect(syn.name)
, а не syn.name
, однако всякий раз, когда я это делаю, код входит в бесконечный цикл до такой степени, что мне просто нужно завершить запрос. Это происходит, даже если я пишу LIMIT 1
в конце. Почему это collect()
происходит?
Ответ №1:
Ваш MATCH
— декартово произведение в сочетании с (неопределенными) путями переменной длины. Это очень интенсивный запрос.
Я бы разделил запрос на (1) сопоставление синонимов, а затем (2) получение дополнительной информации об узле:
MATCH (seed:Seed_Term {name: "valuation"})-[r]-(syn), (n)
WHERE (n:Title OR n:Text OR n:Column OR n:RowName OR n:Cell)
AND (
n.name =~ "(?i).*" syn.name ".*" // case insensitive regular expression
OR n.content =~ "(?i).*" syn.name ".*"
)
WITH seed, n, r, collect(syn.name) AS synonyms
MATCH (n)<-[*]-(z:Pdf)<-[*]-(b:Label)
RETURN n.name AS node,
synonyms,
seed.name AS seed_term,
b.labelName AS company,
z.year AS year,
type(r) AS rel_type
LIMIT 1000
Я не проверял этот запрос, но, возможно, он приведет вас в правильном направлении.