그래프 패턴 일치를 사용하면 직관적인 시각적 구문을 사용하여 찾으려는 데이터의 구조를 설명할 수 있습니다. 테이블을 조인하는 대신 관계 자체처럼 보이는 패턴(에지로 연결된 노드)을 작성합니다. 이 문서에서는 Microsoft Fabric 그래프의 일반적인 시나리오에 대한 GQL 패턴 쿼리를 작성하는 방법을 보여 줍니다.
이 예제에서는 소셜 네트워크 샘플 데이터 세트를 사용합니다. 전체 패턴 구문 참조는 GQL 그래프 패턴을 참조하세요.
이 글을 통해 노드, 엣지, 경로 패턴을 구성하고 결합하는 방법을 배워보세요. 이웃을 찾거나 관계가 없는 엔터티를 찾는 것과 같이 바로 활용할 수 있는 작업은 Write common GQL queries를 참조하세요. 필터링, 그룹화, 집계 워크플로우에 대해서는 '그래프 데이터 필터링 및 집계'를 참조하세요.
사전 요구 사항
- 소셜 네트워크 샘플 데이터셋에서 생성된 그래프 항목으로, 노드 유형, 엣지 유형, 그리고 소셜 네트워크 스키마 예시에 설명된 속성들이 포함되어 있습니다.
- 기본
MATCH및RETURN쿼리에 대해 잘 알고 있습니다. GQL 언어 가이드를 참조하세요.
직접적 관계 일치
기본 패턴은 노드 형식, 특정 에지 형식 및 다른 노드 형식과 일치합니다. 구문은 관계의 다이어그램처럼 보입니다.
예를 들어, 특정 회사에서 근무하는 최대 100명의 사람을 찾아보세요.
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name
LIMIT 100
방향을 모르거나 신경 쓰지 않는 경우 원치 않는 에지 패턴을 사용합니다. 예를 들어 연결을 시작한 사용자에 관계없이 최대 100명의 상호 지인을 찾으려면 다음을 수행합니다.
MATCH (a:Person)-[:knows]-(b:Person)
RETURN a.firstName, b.firstName
LIMIT 100
메모
그래프는 현재 원치 않는 에지 만들기를 지원하지 않지만 구문을 사용하여 -[:label]- 어떤 방향으로든 에지를 쿼리할 수 있습니다.
인라인 WHERE를 사용하여 패턴 필터링
어떤 노드나 엣지가 매치에 참여할 수 있는지 조건이 정의할 때 패턴 안에 넣 WHERE 습니다. 완성된 매칭을 포스트필터하기 위해 문장 수준의 MATCH ... WHERE 조건을 사용하거나, 이전 문장이 생성한 행에 조건이 적용될 때는 별도의 FILTER 조건을 사용하세요. 조건자 배치에 따라 최단 경로 결과가 달라질 수 있습니다. 자세한 내용은 경로 선택 전이나 후에 조건자 배치를 참조하세요.
예를 들어 이름이 'A'로 시작하는 회사에서 일하는 1990년 이전에 태어난 사람을 찾으려면 다음을 수행합니다.
MATCH (p:Person WHERE p.birthday < 19900101)-[:workAt]->(c:Company WHERE c.name STARTS WITH 'A')
RETURN p.firstName, p.lastName, c.name
에지 속성을 필터링하여 일치하는 관계를 제한합니다. 예를 들어 2010년 이상 회사에서 일하기 시작한 사용자만 반환하려면 다음을 수행합니다.
MATCH (p:Person)-[w:workAt WHERE w.workFrom >= 2010]->(c:Company)
RETURN p.firstName, c.name, w.workFrom
다중 홉 관계의 일치
가변 길이 패턴을 사용하여 하나의 식에서 여러 홉을 탐색합니다. 구문을 사용하여 최소 및 최대 홉 {min,max} 수를 지정합니다.
예를 들어, Alice로부터 2~4 단계의 우정을 통해 찾을 수 있는 사람의 수는 최대 100명입니다.
MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{2,4}(dst:Person)
RETURN dst.firstName, dst.lastName
LIMIT 100
Alice에서 최대 100개의 직접 연결 및 2차 연결(하나 또는 두 개의 홉)을 찾으려면 다음을 수행합니다.
MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,2}(dst:Person)
RETURN DISTINCT dst.firstName, dst.lastName
LIMIT 100
경로 모드를 사용하여 순회 제어
기본적으로 GQL은 WALK를 사용하며, 이는 노드와 엣지의 반복을 허용합니다. 더 엄격한 원소 고유성이 필요할 때는 다른 경로 모드를 사용하세요.
| 경로 모드 | 작동 방식 | 사용할 때... |
|---|---|---|
WALK |
노드와 엣지 반복 허용(기본값) | 유한한 범위 내의 일치하는 모든 경로를 원합니다. |
TRAIL |
반복되는 가장자리 없음 | 같은 엣지를 다시 추적하지 않으려 하지만, 같은 노드가 다른 엣지를 통해 나타날 수 있습니다. |
SIMPLE |
시작 및 종료 노드가 공유된 외에는 반복 노드가 없고, 반복되는 간선도 없습니다 | 경로 중간에 노드를 두 번 이상 표시하지 않고 시작에 다시 닫는 경로를 허용하려고 합니다. 루프를 검색하는 데 유용합니다. |
ACYCLIC |
반복되는 노드나 간선 없음 | 경로의 아무 곳에도 노드가 두 번 이상 표시되지 않는지 확인해야 합니다. 엄격한 계층, 계보 또는 노드를 다시 방문하면 잘못된 결과가 생성되는 모든 순회에 사용합니다. |
WALK 는 가장 허용 모드이며 ACYCLIC 가장 제한적입니다.
ACYCLIC 및 SIMPLE의 경우, 엣지 유일성은 노드 유일성으로부터 따른다. 경로는 SIMPLE 첫 번째 노드로 돌아가 닫을 수 있지만, 여전히 엣지를 재사용할 수는 없습니다.
차이점을 설명하기 위해 Alice → Bob → Carol → Bob의 경로를 고려합니다.
- WALK — 이 경로를 허용합니다. 노드와 에지는 자유롭게 반복할 수 있습니다.
- TRAIL - 이 경로를 허용합니다. Bob은 두 번 나타나지만 사용된 각 가장자리는 서로 다른 관계입니다(Alice→Bob 및 Carol→Bob은 고유한 가장자리이므로 가장자리가 반복되지 않습니다.
- SIMPLE — 이 경로를 차단합니다. Bob이 두 번 이상 나타나고 SIMPLE에서는 노드가 경로의 시작과 끝(닫힌 주기)인 경우에만 반복할 수 있습니다. 여기서 Alice는 시작이고 Bob은 끝이므로 예외는 적용되지 않습니다.
- ACYCLIC — 이 경로를 차단합니다. Bob은 경로의 아무 곳이나 두 번 이상 나타납니다.
다음 예제는 Alice의 네트워크에서 4개의 홉 내에 연결할 수 있는 처음 100명의 사용자 각각으로 이어지는 고유 경로의 수를 TRAIL를 사용하여 계산하는 방법을 보여 줍니다.
MATCH TRAIL (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
LET personId = dst.id
RETURN personId, dst.firstName, dst.lastName, count(*) AS pathCount
GROUP BY personId, dst.firstName, dst.lastName
ORDER BY pathCount DESC
LIMIT 100
ACYCLIC를 사용하여 경로의 각 사람이 고유한 4개의 홉 내에서 Alice로부터 연결할 수 있는 최대 100명을 반환합니다.
MATCH ACYCLIC (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
RETURN dst.firstName, dst.lastName
LIMIT 100
기본 REPEATABLE ELEMENTS 매칭 모드는 동일한 그래프 패턴 내에서 각각 다른 경로에서 엣지를 재사용할 수 있게 합니다. 모든 경로에 걸친 모든 에지 바인딩이 서로 달라야 하는 경우 DIFFERENT EDGES 또는 DIFFERENT RELATIONSHIPS를 사용하세요:
MATCH DIFFERENT EDGES
(p:Person)-[:knows]->(friend:Person),
(p)-[:knows]->(other:Person)
RETURN p.firstName, friend.firstName, other.firstName
LIMIT 100
최단 경로 하나를 반환합니다
ALL 는 기본 경로 탐색이며, 모든 일치하는 경로를 반환합니다. 각 출발지-목적지 쌍에 대해 최단 경로 하나를 반환하는 데 사용 ANY SHORTEST 하세요. 다음 쿼리는 Alice에서 Bob까지의 최단 경로를 찾습니다:
MATCH p = ANY SHORTEST
(src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}
(dst:Person WHERE dst.firstName = 'Bob')
RETURN p, path_length(p) AS hopCount
여러 최단 경로가 일치할 때, 어떤 경로가 반환되는지는 결정적이지 않습니다.
ALL SHORTEST
ANY 경로 탐색도 지원되지 않습니다.
술어 배치는 ANY SHORTEST의 결과를 바꿀 수 있습니다. 인라인 노드와 엣지 술어는 어떤 경로가 적격한지 제한하며, 포스트필터는 더 긴 경로를 선택하지 않고 선택한 경로를 제거할 수 있습니다.
경로 선택 앞이나 뒤에 장소 조건자 배치를 참조하세요.
Tip
예측 가능한 쿼리 비용에 대해 유한한 상한을 선호합니다. 무한정 ALL WALK 패턴은 지원되지 않습니다. 무한한 패턴 TRAIL은 , SIMPLE, ACYCLIC 또는 원소 유일성을 통해 종료되지만 여전히 많은 경로를 반환할 수 있습니다. Unbounded ANY SHORTEST WALK 는 특정 쿼리 형태만 지원합니다.
현재 제한 사항을 참조하세요.
변수 재사용을 사용하여 공유 엔터티 표현
패턴의 두 부분에서 동일한 변수를 다시 사용하면 암시적 같음 제약 조건이 만들어집니다. 두 참조 모두 동일한 노드와 일치해야 합니다. 이 기술을 통해 "공유 세 번째 엔터티를 통해 연결된 엔터티 찾기"를 표현할 수 있습니다.
예를 들어, 서로를 알고 같은 회사에서 일하는 최대 100 쌍의 사람들을 찾으려면 다음을 수행합니다.
MATCH (c:Company)<-[:workAt]-(a:Person)-[:knows]-(b:Person)-[:workAt]->(c)
RETURN a.firstName, b.firstName, c.name
LIMIT 100
변수 c 는 두 대상에 workAt 다시 사용되므로 쿼리는 두 사람이 서로를 알고 동일한 회사에서 작업하는 쌍만 반환합니다.
모두 같은 게시물을 좋아하는 사람들의 최대 100 쌍을 찾으려면 :
MATCH (a:Person)-[:likes]->(post:Post)<-[:likes]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, post.id
LIMIT 100
Tip
이 WHERE a.id < b.id 조건은 중복 쌍(Alice + Bob 및 Bob + Alice)이 결과에 나타나지 않도록 방지합니다.
여러 패턴 결합
여러 패턴을 쉼표로 구분하여 단일 MATCH패턴으로 나열합니다. 패턴이 동일한 그래프 요소를 결합해야 할 경우 변수를 재사용하세요.
예를 들어 직장과 거주하는 도시와 함께 최대 100명을 찾으려면 다음을 수행합니다.
MATCH (p:Person)-[:workAt]->(c:Company),
(p)-[:isLocatedIn]->(city:City)
RETURN p.firstName, c.name AS company, city.name AS city
LIMIT 100
공유 변수 p 는 두 패턴을 연결합니다. 각 결과 행은 회사와 도시를 가진 한 사람을 나타냅니다.
분리된 패턴도 유효하지만, 이들은 각자의 일치를 이루는 데카르트 곱을 형성합니다. 모든 조합이 의도적으로 필요할 때만 사용하세요. 성능 지침은 효율적인 조인을 위해 공유 변수 사용을 참조하세요.
선택적 관계 일치
모든 노드에 대한 관계가 없을 수 있는 경우에 사용합니다 OPTIONAL MATCH . 일치하지 않는 항목이 있는 행은 NULL 값으로 남아 있으며, 이는 SQL LEFT JOIN과 유사합니다.
예를 들어 고용주가 없는 사람(즉, 회사 열로 돌아오는 사람)을 포함하여 회사 이름을 가진 최대 100명의 사용자를 반환 NULL 합니다.
MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name AS company
LIMIT 100
다음 IS NULL을 사용하여 어떤 회사에서도 일하지 않는 최대 100명의 사람을 찾습니다.
MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
FILTER c IS NULL
RETURN p.firstName, p.lastName
LIMIT 100