要想做好图数据库,必须做图数据库设计,想做好Dgraph,就需要设计好Shema。Shema的语法是必须理解,如果不理解,别人写的Shema,我们也看不懂。我这里也是走马观花式的记录,细节还需要在使用的时候去慢慢理解。看完这篇文章,别人写的Shema,是能看懂的。
1、数据类型
1.1、标量类型
Schema 的标量数据类型有以下几种,Int,Float,String,Boolean,DateTime。还有一种数组类型或者list类型,比如["e1", "e1", "e2"]。
下面是各种类型的定义例子,其中Float 是个list。
type User {
userID: ID!
name: String!
lastSignIn: DateTime
recentScores: [Float]
reputation: Int
active: Boolean
}
1.2、ID类型
可以用ID 类型标记每个节点的唯一字段类型。ID类型可以自动编码,不变的,不重复的。
例如
type Post {
id: ID!
...
}
1.3、枚举类型
你可以定义枚举类型,示例如下
enum Tag {
GraphQL
Database
Question
...
}
type Post {
...
tags: [Tag!]!
}
1.4、接口
GraphQL允许你定义接口,节点需要继承父类型的属性,继承的属性和类型都需要一致,示例如下:
interface Fruit {
id: ID!
price: Int!
}
type Apple implements Fruit {
id: ID!
price: Int!
color: String!
}
type Banana implements Fruit {
id: ID!
price: Int!
}
可以多继承,多继承时,除了ID属性,父类的属性名字不可以一样。
interface Shape {
id: ID!
shape: String!
}
interface Color {
id: ID!
color: String!
}
type Figure implements Shape & Color {
id: ID!
shape: String!
color: String!
size: Int!
}
1.5、联合类型
多个类型可以组合成一个类型
enum Category {
Fish
Amphibian
Reptile
Bird
Mammal
InVertebrate
}
interface Animal {
id: ID!
category: Category @search
}
type Dog implements Animal {
breed: String @search
}
type Parrot implements Animal {
repeatsWords: [String]
}
type Cheetah implements Animal {
speed: Float
}
type Human {
name: String!
pets: [Animal!]!
}
union HomeMember = Dog | Parrot | Human
type Zoo {
id: ID!
animals: [Animal]
city: String
}
type Home {
id: ID!
address: String
members: [HomeMember]
}
1.6、密码类型
密码类型 使用关键字@secret。密码类型不可以直接被查询。密码类型用Bsrypt去加密
例如:
type Author @secret(field: "pwd") {
name: String! @id
}
1.7、地理类型
类型主要有Point,Polygon和MultiPolygon。
Point
type Point {
longitude: Float!
latitude: Float!
}
PointList
type PointList {
points: [Point!]!
}
Polygon
type Polygon {
coordinates: [PointList!]!
}
MultiPolygon
type MultiPolygon {
polygons: [Polygon!]!
}
2、节点关系
节点与节点之间有关系相连。Dgraph 可以描述这些关系。用@hasInverse 可以实现双向相连关系。
2.1 、单向关系
type Author {
...
}
type Post {
...
author: Author
}
2.2 、双向关系
type Author {
...
posts: [Post] @hasInverse(field: author)
}
type Post {
...
author: Author
}
3、指令
Dgraph 有很多指令 Directives。知道这些指令的含义,才能看懂和更好的写Shema。
3.1 、 @auth
auth 允许您定义如何对类型的查询/变异应用授权规则。
3.2 、@deprecated
这个指定提醒用户某个属性已经废弃
type MyType {
id: ID!
oldField: String @deprecated(reason: "oldField is deprecated. Use newField instead.")
newField: String
deprecatedField: String @deprecated
}
3.3、@dgraph
这个指定用于自定义名字,类似别名
type Person @dgraph(type: "Human-Person") {
name: String @search(by: [hash]) @dgraph(pred: "name")
age: Int
}
type Human-Person {
name
Person.age
}
3.4、@id
该指令可以指定某个属性是id字段
type User {
username: String! @id
...
}
3.5、@search
该指令用于搜索。
搜索是最多的,也是最复杂的。我这里只是简单介绍了下常用的。对于Int,Float和DateTime ,有下面参数。
It:小于。le:小于等于。eq:等于。in:在内。between:在什么中间。ge:大于等于。gt:大于。
下面是个定义和查询
type Post {
...
numLikes: Int @search
}
query {
queryPost(filter: { numLikes: { gt: 50 }}) {
...
}
}
对于String
比如:
type Post {
title: String @search(by: [term])
text: String @search(by: [fulltext])
...
}
query {
queryPost(filter: { title: { `allofterms: "GraphQL tutorial"` } } ) { ... }
}
地理字段
举个例子
type Hotel {
id: ID!
name: String!
location: Point @search
area: Polygon @search
}
queryHotel(filter: {
location: {
near: {
coordinate: {
latitude: 37.771935,
longitude: -122.469829
},
distance: 1000
}
}
}) {
name
}
3.6、@generate
用于指定哪些Api生效
type Person @generate(
query: {
get: false,
query: true,
aggregate: false
},
mutation: {
add: true,
delete: false
},
subscription: false
) {
id: ID!
name: String!
}
3.7 @withSubscription
用于订阅属性,一般用于WebSoct。