Neptune查询语言概述 #

一、查询语言简介 #

1.1 Neptune支持的查询语言 #

text
查询语言:
├── Gremlin
│   ├── Apache TinkerPop项目
│   ├── 属性图查询语言
│   ├── 图遍历语言
│   └── 命令式查询
└── SPARQL
    ├── W3C标准
    ├── RDF图查询语言
    ├── 声明式查询
    └── 支持推理

1.2 语言特点对比 #

特性 Gremlin SPARQL
数据模型 属性图 RDF图
查询风格 命令式/遍历 声明式/模式匹配
标准化 Apache项目 W3C标准
学习曲线 中等 较陡
推理能力 支持
联邦查询 不支持 支持

二、Gremlin概述 #

2.1 什么是Gremlin #

Gremlin是Apache TinkerPop图计算框架的图遍历语言,用于查询和操作属性图数据。

text
Gremlin特点:
├── 图遍历语言
├── 函数式编程风格
├── 支持复杂遍历操作
├── 多语言驱动支持
└── 可扩展性强

2.2 基本语法 #

查询顶点:

gremlin
// 获取所有顶点
g.V()

// 获取指定ID的顶点
g.V('1')

// 获取指定标签的顶点
g.V().hasLabel('person')

// 获取指定属性的顶点
g.V().has('name', 'Tom')

查询边:

gremlin
// 获取所有边
g.E()

// 获取指定标签的边
g.E().hasLabel('knows')

// 获取指定属性的边
g.E().has('since', 2020)

遍历操作:

gremlin
// 出边遍历
g.V('1').out('knows')

// 入边遍历
g.V('1').in('knows')

// 双向遍历
g.V('1').both('knows')

2.3 查询示例 #

示例1:查询Tom的朋友

gremlin
g.V().has('person', 'name', 'Tom').
  out('knows').
  values('name')

示例2:查询共同好友

gremlin
g.V().has('name', 'Tom').out('knows').
  where(out('knows').has('name', 'Jerry')).
  values('name')

示例3:最短路径

gremlin
g.V().has('name', 'Tom').
  repeat(out().simplePath()).
  until(has('name', 'Jerry')).
  path().
  limit(1)

2.4 Gremlin遍历步骤 #

text
遍历步骤分类:
├── 源步骤(Source Steps)
│   ├── V():顶点源
│   └── E():边源
├── 过滤步骤(Filter Steps)
│   ├── has():属性过滤
│   ├── filter():条件过滤
│   ├── where():条件过滤
│   └── dedup():去重
├── 变换步骤(Transform Steps)
│   ├── out():出边遍历
│   ├── in():入边遍历
│   ├── map():映射
│   └── flatMap():扁平映射
├── 侧效步骤(SideEffect Steps)
│   ├── aggregate():聚合
│   ├── group():分组
│   └── store():存储
└── 终端步骤(Terminal Steps)
    ├── toList():返回列表
    ├── next():返回下一个
    ├── iterate():执行遍历
    └── count():计数

三、SPARQL概述 #

3.1 什么是SPARQL #

SPARQL(SPARQL Protocol and RDF Query Language)是W3C推荐的RDF数据查询语言标准。

text
SPARQL特点:
├── W3C标准
├── 声明式查询
├── 模式匹配
├── 支持推理
├── 联邦查询
└── 多种查询形式

3.2 基本语法 #

SELECT查询:

sparql
PREFIX ex: <http://example.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?name ?age
WHERE {
  ?person a ex:Person .
  ?person foaf:name ?name .
  ?person ex:age ?age .
}

ASK查询:

sparql
PREFIX ex: <http://example.org/>

ASK {
  ex:Tom ex:knows ex:Jerry .
}

CONSTRUCT查询:

sparql
PREFIX ex: <http://example.org/>

CONSTRUCT {
  ?person ex:friend ?friend .
}
WHERE {
  ?person ex:knows ?friend .
  ?friend ex:knows ?person .
}

DESCRIBE查询:

sparql
PREFIX ex: <http://example.org/>

DESCRIBE ex:Tom

3.3 查询示例 #

示例1:查询Tom的朋友

sparql
PREFIX ex: <http://example.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?friendName
WHERE {
  ex:Tom foaf:name "Tom" .
  ex:Tom ex:knows ?friend .
  ?friend foaf:name ?friendName .
}

示例2:查询共同好友

sparql
PREFIX ex: <http://example.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?mutualFriend
WHERE {
  ex:Tom ex:knows ?mutualFriend .
  ex:Jerry ex:knows ?mutualFriend .
  ?mutualFriend foaf:name ?mutualFriend .
}

示例3:路径查询

sparql
PREFIX ex: <http://example.org/>

SELECT ?path
WHERE {
  ex:Tom (ex:knows/ex:knows) ?target .
  ?target foaf:name ?path .
}

3.4 SPARQL查询形式 #

text
查询形式:
├── SELECT
│   └── 返回变量绑定结果
├── ASK
│   └── 返回布尔值
├── CONSTRUCT
│   └── 构建新的RDF图
└── DESCRIBE
    └── 描述资源

四、语言选择指南 #

4.1 按应用场景选择 #

场景 推荐语言 原因
社交网络 Gremlin 高效图遍历
知识图谱 SPARQL 语义推理
欺诈检测 Gremlin 复杂模式匹配
数据集成 SPARQL 联邦查询
推荐系统 Gremlin 快速遍历
语义搜索 SPARQL 本体支持

4.2 按技术背景选择 #

背景 推荐语言 原因
SQL背景 SPARQL 声明式语法相似
编程背景 Gremlin 命令式风格
语义网背景 SPARQL 熟悉RDF概念
图论背景 Gremlin 遍历思维

4.3 按功能需求选择 #

功能需求 Gremlin SPARQL
复杂遍历 ✅ 优秀 ⚠️ 一般
模式匹配 ⚠️ 一般 ✅ 优秀
推理能力 ❌ 不支持 ✅ 支持
联邦查询 ❌ 不支持 ✅ 支持
多值属性 ✅ 原生支持 ⚠️ 需要扩展
事务控制 ✅ 支持 ✅ 支持

五、Gremlin详解 #

5.1 遍历源 #

gremlin
// 创建遍历源
g = traversal().withRemote(connection)

// 从顶点开始
g.V()

// 从边开始
g.E()

// 从指定顶点开始
g.V('1', '2', '3')

5.2 过滤操作 #

gremlin
// has()过滤
g.V().has('name', 'Tom')
g.V().has('age', gt(25))
g.V().has('name', within('Tom', 'Jerry'))

// where()过滤
g.V().where(out('knows').count().is(gt(5)))

// filter()过滤
g.V().filter(outE().count().is(gt(0)))

// dedup()去重
g.V().out('knows').dedup()

5.3 变换操作 #

gremlin
// map()映射
g.V().map(values('name'))

// flatMap()扁平映射
g.V().flatMap(out('knows'))

// select()选择
g.V().as('a').out('knows').as('b').select('a', 'b')

// path()路径
g.V().out('knows').path()

5.4 聚合操作 #

gremlin
// count()计数
g.V().count()

// group()分组
g.V().group().by('label').by(count())

// order()排序
g.V().order().by('name', asc)

// sum()求和
g.V().values('age').sum()

5.5 修改操作 #

gremlin
// 添加顶点
g.addV('person').property('name', 'Tom')

// 添加边
g.addE('knows').from(V('1')).to(V('2'))

// 设置属性
g.V('1').property('age', 30)

// 删除顶点
g.V('1').drop()

// 删除属性
g.V('1').properties('age').drop()

六、SPARQL详解 #

6.1 基本图模式 #

sparql
# 简单三元组模式
SELECT ?s ?p ?o
WHERE {
  ?s ?p ?o .
}

# 多三元组模式
SELECT ?name ?email
WHERE {
  ?person foaf:name ?name .
  ?person foaf:mbox ?email .
}

6.2 过滤表达式 #

sparql
# 数值过滤
SELECT ?name ?age
WHERE {
  ?person foaf:name ?name .
  ?person ex:age ?age .
  FILTER (?age > 25)
}

# 字符串过滤
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER (STRSTARTS(?name, "T"))
}

# 正则过滤
SELECT ?name
WHERE {
  ?person foaf:name ?name .
  FILTER (REGEX(?name, "^T", "i"))
}

6.3 可选模式 #

sparql
# OPTIONAL
SELECT ?name ?email
WHERE {
  ?person foaf:name ?name .
  OPTIONAL { ?person foaf:mbox ?email }
}

6.4 联合模式 #

sparql
# UNION
SELECT ?name
WHERE {
  {
    ?person foaf:firstName ?name .
  }
  UNION
  {
    ?person foaf:lastName ?name .
  }
}

6.5 属性路径 #

sparql
# 路径表达式
SELECT ?friend
WHERE {
  ex:Tom foaf:knows+ ?friend .
}

# 路径操作符
# * : 零次或多次
# + : 一次或多次
# ? : 零次或一次
# / : 路径序列
# | : 路径选择
# ^ : 反向路径

6.6 更新操作 #

sparql
# INSERT DATA
INSERT DATA {
  ex:Tom foaf:name "Tom" .
  ex:Tom ex:age 30 .
}

# DELETE DATA
DELETE DATA {
  ex:Tom ex:age 30 .
}

# DELETE/INSERT
DELETE {
  ex:Tom ex:age ?oldAge .
}
INSERT {
  ex:Tom ex:age 31 .
}
WHERE {
  ex:Tom ex:age ?oldAge .
}

七、语言互操作 #

7.1 模型转换 #

text
属性图 → RDF转换:
├── 顶点 → URI资源
├── 标签 → rdf:type
├── 属性 → 谓语
└── 边 → 三元组

7.2 查询等价 #

Gremlin:

gremlin
g.V().has('name', 'Tom').out('knows').values('name')

SPARQL等价:

sparql
SELECT ?friendName
WHERE {
  ?tom foaf:name "Tom" .
  ?tom ex:knows ?friend .
  ?friend foaf:name ?friendName .
}

八、性能对比 #

8.1 查询性能 #

查询类型 Gremlin SPARQL
简单查询
复杂遍历 更快 一般
模式匹配 一般 更快
聚合查询

8.2 优化建议 #

Gremlin优化:

gremlin
// 使用索引过滤
g.V().hasLabel('person').has('name', 'Tom')

// 限制遍历深度
g.V().repeat(out()).times(3)

// 使用limit()
g.V().limit(100)

SPARQL优化:

sparql
# 使用FILTER减少中间结果
SELECT ?name
WHERE {
  ?person a ex:Person .
  ?person foaf:name ?name .
  FILTER (STRSTARTS(?name, "T"))
}

# 使用BIND预计算
SELECT ?fullName
WHERE {
  ?person foaf:firstName ?first .
  ?person foaf:lastName ?last .
  BIND(CONCAT(?first, " ", ?last) AS ?fullName)
}

九、客户端驱动 #

9.1 Gremlin驱动 #

Python:

python
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from gremlin_python.process.anonymous_traversal import traversal

connection = DriverRemoteConnection('wss://endpoint:8182/gremlin', 'g')
g = traversal().withRemote(connection)

JavaScript:

javascript
const gremlin = require('gremlin');
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
const traversal = gremlin.process.AnonymousTraversalSource.traversal;

const connection = new DriverRemoteConnection('wss://endpoint:8182/gremlin');
const g = traversal().withRemote(connection);

Java:

java
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal;

Cluster cluster = Cluster.build("endpoint").port(8182).create();
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster));

9.2 SPARQL驱动 #

Python:

python
from SPARQLWrapper import SPARQLWrapper, JSON

sparql = SPARQLWrapper('https://endpoint:8182/sparql')
sparql.setQuery('SELECT ?s WHERE { ?s ?p ?o } LIMIT 10')
sparql.setReturnFormat(JSON)
results = sparql.query().convert()

JavaScript:

javascript
const fetch = require('node-fetch');

const endpoint = 'https://endpoint:8182/sparql';
const query = 'SELECT ?s WHERE { ?s ?p ?o } LIMIT 10';

const response = await fetch(`${endpoint}?query=${encodeURIComponent(query)}`, {
  headers: { 'Accept': 'application/sparql-results+json' }
});
const results = await response.json();

十、总结 #

查询语言选择要点:

因素 Gremlin SPARQL
数据模型 属性图 RDF
查询风格 命令式 声明式
学习难度 中等 较高
适用场景 图遍历 语义查询

下一步,让我们学习图数据库概念!

最后更新:2026-03-27