簡體   English   中英

SQL 服務器圖形數據庫 - 使用多種邊類型的最短路徑

[英]SQL Server Graph Database - shortest path using multiple edge types

我已經對 SQL Server GraphDB 進行了研究,但是到目前為止我發現的所有人為示例都只使用了一個邊表。 例如,它總是Person-friend_of->Person 就我而言,我在我們的數據中心創建了一個已部署軟件組件的圖表,並且存在不同的邊緣/關系。 諸如Application-connects_to->SqlDatabaseServer-hosts->Application

我想編寫一個查詢,它將向我顯示任意兩個節點之間的最短路徑,而不管使用的邊緣如何。 我想如果我使用的是 Neo4j,我會把MATCH寫成這樣:

Server-*->SqlDatabase注意星號。

在 SQL 服務器中是否有慣用的方法來執行此操作?

自 SQL Server 2019 起,您可以使用派生表或視圖完全做到這一點。 我找不到任何有關此功能的官方文檔,但我在有關材料清單的視頻中發現了一個小注釋。

編輯:他們在該視頻中有一些鏈接: Github 示例

關鍵是您使用多個EDGE (或NODE )表的UNION ALL來充當MATCH運算符中的一個EDGE (或NODE )表。

  • 您可以使用SUBSELECT
  • 不能使用公用表表達式(雖然我沒有特別努力,但我無法讓它工作)
  • 您可以使用視圖

還有一個例子:

BEGIN TRANSACTION; --if you execute code found on internet without any scrutiny and have "people" table in your database
GO

  DROP TABLE IF EXISTS people, knows, killed, likes;

  CREATE TABLE people (Name VARCHAR(100)) AS NODE;
  CREATE TABLE knows AS EDGE;
  CREATE TABLE killed AS EDGE;
  CREATE TABLE likes AS EDGE;

  INSERT INTO people
    (Name)
  VALUES
    ('A'),
    ('B'),
    ('C'),
    ('D'),
    ('E')

  INSERT INTO knows
    ($from_id, $to_id)
  SELECT
    knows.$node_id, known.$node_id
  FROM
    people AS knows,
    people AS known
  WHERE
    knows.Name = 'A' AND known.Name = 'B';

  INSERT INTO killed
    ($from_id, $to_id)
  SELECT
    killed.$node_id, victim.$node_id
  FROM
    people AS killed,
    people AS victim
  WHERE
    (killed.Name = 'A' AND victim.Name = 'C')
    OR (killed.Name = 'C' AND victim.Name = 'E');

  INSERT INTO likes
    ($from_id, $to_id)
  SELECT
    likes.$node_id, liked.$node_id
  FROM
    people AS likes,
    people AS liked
  WHERE
    likes.Name = 'A' AND liked.Name = 'D';

  SELECT
    P1.Name AS First_in_chain,
    LAST_VALUE(P2.Name) WITHIN GROUP (GRAPH PATH) AS Last_in_chain
  FROM
    people AS P1,
    people FOR PATH AS P2,
    ------------------------------------------------------------------
    ---------this is a compound of edges
    (
      SELECT * FROM knows
      UNION ALL
      SELECT * FROM killed
      UNION ALL
      SELECT * FROM likes
    ) FOR PATH AS RELATION
    ------------------------------------------------------------------
  WHERE
    MATCH(
      SHORTEST_PATH(
        P1(-(RELATION)->P2)+
      )
    )
    AND P1.NAME = 'A'
  OPTION(RECOMPILE);

  DROP TABLE IF EXISTS people, knows, killed, likes;

GO
  IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM