Подтвердить что ты не робот

Neo4j: сопоставление нескольких ярлыков (2 или более)

Я хотел бы выполнить поиск, и я хотел бы начать перемещение из двух меток (условие ИЛИ). Например, мне нужно узнать все узлы, у которых есть метки либо "Мужской", либо "Женский" и чье свойство, name = ~ '.ail.'.

4b9b3361

Ответ 1

Вы можете поместить это в предложение WHERE:

MATCH n
WHERE n:Male OR n:Female
RETURN n

ИЗМЕНИТЬ

Как указывает @tbaum, это выполняет AllNodesScan. Я написал ответ, когда метки были довольно новыми и ожидали, что планировщик запросов в конечном итоге реализует его с помощью NodeByLabelScan для каждой метки, как это делает для случая с одной меткой

MATCH n
WHERE n:Male
RETURN n

Я все еще думаю, что это разумное выражение запроса и что разумно ожидать, что планировщик запросов будет реализовывать его с помощью проверки меток, но с Neo4j 2.2.3 запрос по-прежнему реализуется с помощью AllNodesScan и фильтр метки. Вот, следовательно, более подробная альтернатива. Поскольку дизъюнкция метки означает объединение единиц, и этот союз может быть выражен по-разному, мы можем выразить его так, чтобы планировщик запросов реализовывал без сканирования всех узлов и вместо этого начинал с NodeByLabelScan на метку.

MATCH (n:Male)
WHERE n.name =~ '.ail.'
RETURN n
UNION MATCH (n:Female)
WHERE n.name =~ '.ail.'
RETURN n

Это означает выражение запроса для каждой метки и присоединение к ней с явным UNION. Это не является необоснованным, по крайней мере, для меньшего количества меток, но мне непонятно, почему планировщики запросов не могут вывести одну и ту же реализацию из более простого запроса, поэтому я открыл проблему github здесь.

Ответ 2

MATCH n WHERE n:Label1 OR n:Label2

... приведет к AllNodesScan, это плохая идея!

возможно лучшее решение:

OPTIONAL MATCH (n1:Label1)
WITH collect(distinct n1) as c1

OPTIONAL MATCH (n2:Label2) 
WITH collect(distinct n2) + c1 as c2

OPTIONAL MATCH (n3:Label3) 
WITH collect(distinct n3) + c2 as c3

UNWIND c3 as nodes
RETURN count(nodes),labels(nodes)