Dgraph QL 入門

barryz發表於2018-04-25

0x01 HelloWorld(簡單查詢)

{
    find_someone(func: eq(name, "SomeOne's name")) {
        uid
        name
        age
        sex
    }
}
複製程式碼

上面的查詢語句表示, 新建一個名為 find_someone 的query, 查詢條件為集合內name等於 SomeOne's name的實體, 並返回 uid, name, age, sex 欄位。 其中 uid 是 dgraph 內部的用來標識entity的唯一identify, 是一個16進位制的數. 也可以通過uid 來查詢某個entity:

{
    find_someone(func: uid(0x6)) {
        name
        age
        sex
        uid
        someFieldNotFound # 如果欄位不存在,則不顯示,不會報錯
    }
}
複製程式碼

0x02 關係查詢

可以查詢某entity和另外的entity的關係(edge)

{
    find_someone(func: eq(name, "Michael")) {
        name
        age
        uid
        owner_pet {  # 查詢Michael擁有的寵物
            name
        }
        friend { # 查詢Michael的朋友
            name
            age
            uid
            friend {
                name # 查詢Michael朋友的朋友
            }
        }
    }
}
複製程式碼

Response:

{
  "data": {
    "find_someone": [
      {
        "name": "Michael",
        "age": 39,
        "uid": "0x3",
        "friend": [
          {
            "age": 35,
            "uid": "0x4",
            "friend": [
              {
                "name": "Michael"
              }
            ]
          },
          {
            "age": 24,
            "uid": "0x5",
            "friend": [
              {
                "name": "Catalina"
              }
            ]
          },
          {
            "name": "Catalina",
            "age": 19,
            "uid": "0x6"
          },
          {
            "age": 35,
            "uid": "0x7"
          },
          {
            "name": "Sarah",
            "age": 55,
            "uid": "0xa"
          }
        ]
      }
    ]
  }
複製程式碼

0x03 資料型別和節點

Dgraph中可用的資料型別有:

  • int signed 64 bit integer
  • float double precision floating point number
  • string string
  • bool boolean
  • id ID’s stored as strings
  • dateTime RFC3339 time format with optional timezone eg: 2006-01-02T15:04:05.999999999+10:00 or 2006-01-02T15:04:05.999999999
  • geo geometries stored using go-geom
  • uid uid

0x04 多語言支援

Dgraph支援UTF-8編碼的字串文字查詢.

字串值謂詞可以用language tag進行註釋.

比如:

    "Lily"@en # 表示以英文儲存
    "अमित"@hi # 表示以菲律賓語儲存
    "상현"@ko  # 表示以韓文儲存
    "張三"@ch  # 表示中文儲存
複製程式碼

Query可以通過以哪種語言搜尋以及以哪種語言返回來搜尋帶Tag語言的文字. 如果是以此種格式要求返回: @lang1:...:langN, 則需遵循以下規則:

  • 至少返回一個結果
  • 如果結果存在於首選語言中,則返回最左邊(在首選項列表中)的結果
  • 如果結果不存在於首選語言中,則不返回結果,除非首選項列表以.結尾,在這種情況下,將返回沒有指定語言的值.

0x05 函式和過濾

節點根據應用於節點edge的函式進行過濾.

過濾不僅可以應用在查詢的頂級節點上, 事實上, 查詢過濾可以應用在任何節點上.

下列是一些常用的過濾函式:

  • allOfTerms(edge_name, "term1 ... termN"): 以任何順序匹配符合所有指定模式的字串;不區分大小寫

  • anyOfTerms(edge_name, "term1 ... termN"): 以任何順序匹配符合任何指定模式的字串;不區分大小寫

  • 等值或不等值查詢過濾, 可以用來比較的型別有: int, float, stringdate.

    1. eq(edge_name, value): 等於
    2. ge(edge_name, value): 大於等於
    3. le(edge_name, value): 小於等於
    4. gt(edge_name, value): 大於
    5. lt(edge_name, value): 小於
  • 還有其他過濾函式諸如: regular expression, full text search, geo search

eg.

{
    filter_friend(func: allofterms(name, "Michael")) {
        name
        age
        friend @filter(le(age, 27)) { # 子過濾, 過濾出年齡小於27的朋友..
          name@. # tag 為 . , 表示顯示所有語言類別的name
          age
        }
    }
}
複製程式碼

Response:

{
  "data": {
    "filter_friend": [
      {
        "name": "Michael",
        "age": 39,
        "friend": [
          {
            "name@.": "Sang Hyun",
            "age": 24
          },
          {
            "name@.": "Catalina",
            "age": 19
          }
        ]
      }
    ]
  }
}
複製程式碼

0x06 邏輯運算(AND, OR and NOT)

邏輯操作符 AND, ORNOT 可以在一個filter中組合多個function.

eg.

{
  filter_test(func: anyofterms(name, "Michael")) {
    age
    name
    friend @filter(lt(age, 40) AND gt(age, 20)) { # 過濾大於20且小於40的friend.
      name@.
      age
    }
  }
}

{
  filter_test(func: anyofterms(name, "Michael")) {
    age
    name
    friend @filter(NOT ge(age, 20)) { # 過濾小於20的friend.
      name@.
      age
    }
  }
}
複製程式碼

注意: 邏輯操作符不能直接用於func關鍵字之後, 比如:

{
  filter_xxx(func: AND allofterms()) ... # 報錯
}
複製程式碼

0x07 排序

查詢結果可以使用 orderascorderdesc 來升降序排序.

排序結果只會在JSON Response中才會體現.

eg.

{
  filter_test(func: allofterms(name, "Michael")) {
    age
    name
    friend (orderdesc: age) { # 以age倒序排列
      name@.
      age
    }
  }
}
複製程式碼

0x08 分頁(offset, first, after)

通常來說,一個查詢返回上萬的結果的情況並不罕見.

有些場景下, 我們可能不需要這麼多的資料,或者只是需要 top-K 的資料, 對結果進行分頁顯示,或者limit一些結果.

GraphQL+- 語法中, 關鍵字: offset, first, after 可以和排序功能組合使用.

  • first: N 返回前N個結果
  • offset: N 跳過前N個結果
  • after: uid 返回該uid之後的資料

這裡的N必須是無符號整型

預設的, 查詢結果通過uid進行排序.

eq.

{
  filter_test(func: allofterms(name, "Michael")) {
    age
    name
    friend (orderdesc: name@., first: 2, offset: 1) { 
      name@.
      age
    }
  }
}
複製程式碼

0x09 計數(Count)

使用 count 函式可以統計結果集中的edges個數.

eg.

{
  filter_test(func: anyofterms(name, "Michael")) {
    age
    name
    count(friend)
  }
}
複製程式碼

Response:

"data": {
    "filter_test": [
      {
        "age": 39,
        "name": "Michael",
        "count(friend)": 5
      }
    ]
  }
}
複製程式碼

相關文章