Выбрать главу

MATCH p=(u: User)-[: MemberOf*1..]->(g: Group) RETURN p

Другой пример – получить все компьютеры, где пользователи являются локальными администраторами:

MATCH p=(u: User)-[: MemberOf|AdminTo*1..]->(c: Computer) RETURN p

Короткие пути

Построение графа со всеми непрямыми связями потребует большого количества ресурсов, и, скорей всего, база не выдержит и упадет. Для решения этой проблемы можно использовать операторы ShortestPath и AllShortestPaths. Разница между ними в том, что первый находит один короткий путь, а второй – все, при условии, что они существуют.

Для использования коротких путей необходимо поместить шаблон в круглые скобки. Так, предыдущий пример будет выглядеть следующим образом:

MATCH p=ShortestPath((u: User)-[*1..]->(c: Group)) RETURN p

Совет

Ограничение количества переходов поможет найти самые короткие пути.

В интерфейсе BloodHound в форме Поиск путей (Pathfinding) используется оператор AllShortestPaths, который применяется для поиска коротких путей между двумя указанными узлами.

Оператор OPTIONAL MATCH

Оператор OPTIONAL MATCH работает точно так же, как и MATCH; разница в том, что при использовании OPTIONAL MATCH будет добавлять NULL для недостающих элементов.

Рассмотрим два примера, в которых будем искать локальных администраторов на компьютерах с помощью операторов MATCH и OPTIONAL MATCH.

MATCH (u: User)

MATCH (u)-[r: AdminTo]->(c: Computer)

RETURN u.name, c.name

Рис. 3.10. Результат с MATCH

MATCH (u: User)

OPTIONAL MATCH (u)-[r: AdminTo]-(c: Computer)

RETURN u.name, c.name

Рис. 3.11. Результат с OPTIONAL MATCH

Как можно увидеть на рисунке 3.11, там, где нет прав локального администратора, neo4j выставил null. То же самое в графическом представлении: мы получим всех пользователей, и только у некоторых будет связь AdminTo с компьютерами.

Рис. 3.12. Графическое представление OPTIONAL MATCH

Условия фильтрации запросов

Ранее мы уже использовали фильтры по меткам User и Computer, но только в некоторых случаях этого будет достаточно. Для указания более точных критериев поиска применяется оператор WHERE, который может относиться ко всем свойствам узла и связи.

Обычно оператор WHERE используется после формирования шаблона, но он может быть применен и внутри узла, и все условия будут относиться только к этому узлу:

MATCH (g: Group) WHERE g.name = "DOMAIN ADMINS@DOMAIN.LOCAL" RETURN g.name

MATCH (g: Group WHERE g.name = "DOMAIN ADMINS@DOMAIN.LOCAL") RETURN g.name

Эти два запроса будут иметь одинаковый вывод, но второй запрос будет читаться сложнее.

Внимание

Помним, что Cypher чувствителен к регистру для свойств узла.

Рассмотрим синтаксис использования оператора WHERE на простых примерах.

Оператор сравнения

Для указания точного вхождения используется оператор сравнения =.

Например, найти всех членов группы администраторов домена:

MATCH (u: User)-[r: MemberOf*0..]->(g: Group) g.name = "DOMAIN ADMINS@DOMAIN.LOCAL" RETURN u.name

Кроме строковых значений могут приниматься булевы значения FALSE и TRUE или числовые. Например, найти все незаблокированные учетные записи компьютеров:

MATCH (c: Computer) WHERE c.enabled = TRUE return c

Другой способ использовать точное вхождение – это указать фильтр запроса в узлах. Фильтр задается в фигурных скобках по шаблону <свойство>:<значение>. Например, определить, на каких машинах используется LAPS, можно следующим образом:

MATCH (c: Computer {haslaps: true}) return c

Можно добавить несколько условий. В таком случае они разделяются запятой. Например, выбрать только незаблокированные объекты и компьютеры, на которых используется LAPS.

MATCH (c: Computer {enabled: true, haslaps: true}) return c

Если мы хотим указать метку в операторе WHERE, то вместо знака равенства используется двоеточие.

MATCH (c) WHERE c: User RETURN c

Имя связи тоже можно указывать в WHERE. В данном случае используется type(), так как у связи нет свойства имени.

MATCH p=(c: Computer)-[r]->(u: User) WHERE type(r) = "HasSession" RETURN p

Как и узлы, связь может иметь свойства, и фильтрация по ним будет иметь точно такой же принцип. Например, найти все связи между пользователями и компьютерами, где связь имеет свойство isacl в значении TRUE:

MATCH p=(u: User)-[r]-(c: Computer) WHERE r.isacl = TRUE RETURN p

Оператор «не равно»

Оператор не равно <> противоположен предыдущему оператору. Например, найти все группы, которые не являются контроллерами домена:

полную версию книги