改进我的 AQL 查询的想法
Ideas to improve my AQL query
在我的图表中,一个用户连接到许多项目,每个项目可以递归地分为许多子项目。由于我的项目有特定的顺序,我正在考虑这两个选项来为我的数据建模:
现在我想创建一个查询来检索给定用户 ID 的两个级别的项目。这个 AQL 是我的第一次尝试:
for itemId in (for b in board filter b._from == @_from sort b.order return b._to)
for item1 in (for t in item filter t._id == itemId return keep(t, '_id', 'title'))
return merge(item1, {board: (
for itemId2 in (for b in board filter b._from == item1._id sort b.order return b._to)
for t in item filter t._id == itemId2 return keep(t, '_id', 'title')
)})
查询有效并输出如下结果:
[
{
"title": "item 1",
"_id": "item/41260117498",
"board": [
{
"title": "item 4",
"_id": "item/42205736442"
},
{
"title": "item 5",
"_id": "item/42208423418"
}
]
},
{
"title": "item 2",
"_id": "item/41260772858",
"board": []
},
{
"title": "item 3",
"_id": "item/41883233786",
"board": []
}
]
这很好,但我觉得我的查询对于这种简单的遍历来说不必要地复杂。有人可以帮我创造一个更好的吗?
使用 graph database 的要点是利用其图形查询功能让它处理边缘,而不是通过手动连接边缘来自行完成。
我将演示 pattern matching traversals 这样的查询;他们在后台为您透明地处理边缘(_from
和 _to
)的转换。
首先你会create a graph配置你的边关系,为了简单起见,我们使用匿名图。您有边集合 board
和顶点集合 user
和 item
.
首先,您只需让 运行 整个查询以了解其工作原理,然后检查完整结果:
FOR v, e, p IN 1..3 OUTBOUND 'user/andy' board RETURN {v: v, e: e, p: p}
你看你只需要指定起始节点和边集合board
,它会通过检查边自行找到要查询的顶点集合
现在我们可以添加 FILTER
s 来省略我们不喜欢的边和顶点:
FOR v, e, p IN 1..3 OUTBOUND 'user/andy' board
FILTER e.title == 'item 2'
FILTER p.edges[1].title != 'item 1'
RETURN {v: v, e: e, p: p}
该示例包含两个 FILTER
指令;一个是匹配每条边以使 title
属性等于 "item 2"
,另一个是匹配遍历中的第一条边必须包含 title
"item 1"
。
最后我们use document manipulation只得到我们喜欢的文档部分:
FOR v, e, p IN 1..3 OUTBOUND 'user/andy' board
FILTER e.title == 'item 2'
RETURN {v: v, e: {title: e.title, _id: e._id}, pathEdgeTitle: p.edges[*].title}
在我的图表中,一个用户连接到许多项目,每个项目可以递归地分为许多子项目。由于我的项目有特定的顺序,我正在考虑这两个选项来为我的数据建模:
现在我想创建一个查询来检索给定用户 ID 的两个级别的项目。这个 AQL 是我的第一次尝试:
for itemId in (for b in board filter b._from == @_from sort b.order return b._to)
for item1 in (for t in item filter t._id == itemId return keep(t, '_id', 'title'))
return merge(item1, {board: (
for itemId2 in (for b in board filter b._from == item1._id sort b.order return b._to)
for t in item filter t._id == itemId2 return keep(t, '_id', 'title')
)})
查询有效并输出如下结果:
[
{
"title": "item 1",
"_id": "item/41260117498",
"board": [
{
"title": "item 4",
"_id": "item/42205736442"
},
{
"title": "item 5",
"_id": "item/42208423418"
}
]
},
{
"title": "item 2",
"_id": "item/41260772858",
"board": []
},
{
"title": "item 3",
"_id": "item/41883233786",
"board": []
}
]
这很好,但我觉得我的查询对于这种简单的遍历来说不必要地复杂。有人可以帮我创造一个更好的吗?
使用 graph database 的要点是利用其图形查询功能让它处理边缘,而不是通过手动连接边缘来自行完成。
我将演示 pattern matching traversals 这样的查询;他们在后台为您透明地处理边缘(_from
和 _to
)的转换。
首先你会create a graph配置你的边关系,为了简单起见,我们使用匿名图。您有边集合 board
和顶点集合 user
和 item
.
首先,您只需让 运行 整个查询以了解其工作原理,然后检查完整结果:
FOR v, e, p IN 1..3 OUTBOUND 'user/andy' board RETURN {v: v, e: e, p: p}
你看你只需要指定起始节点和边集合board
,它会通过检查边自行找到要查询的顶点集合
现在我们可以添加 FILTER
s 来省略我们不喜欢的边和顶点:
FOR v, e, p IN 1..3 OUTBOUND 'user/andy' board
FILTER e.title == 'item 2'
FILTER p.edges[1].title != 'item 1'
RETURN {v: v, e: e, p: p}
该示例包含两个 FILTER
指令;一个是匹配每条边以使 title
属性等于 "item 2"
,另一个是匹配遍历中的第一条边必须包含 title
"item 1"
。
最后我们use document manipulation只得到我们喜欢的文档部分:
FOR v, e, p IN 1..3 OUTBOUND 'user/andy' board
FILTER e.title == 'item 2'
RETURN {v: v, e: {title: e.title, _id: e._id}, pathEdgeTitle: p.edges[*].title}