通过Slack agheranimesh:
这是我的图表,名为 LibraryGraph :
我的图表查询:
FOR v, e, p IN 1..2 OUTBOUND "User/001" GRAPH "LibraryGraph"
SORT p.vertices[2].Name
RETURN p.vertices[1]
它没有给我我想要的结果。我想要一本书名单按作者姓名排序,没有作者的书籍应该排在最后(B2,B3,B1,B4,B5)。
重新创建数据的脚本(arangosh --javascript.execute <file>
):
db._createDatabase('Library')
db._useDatabase('Library')
const User = db._create('User')
const Book = db._create('Book')
const Author = db._create('Author')
const User_Book = db._createEdgeCollection('User_Book')
const Book_Author = db._createEdgeCollection('Book_Author')
User.save({ '_key': '001', 'UserName': 'U1' })
Book.save({ '_key': 'B1', 'Name': 'B1' })
Book.save({ '_key': 'B2', 'Name': 'B2' })
Book.save({ '_key': 'B3', 'Name': 'B3' })
Book.save({ '_key': 'B4', 'Name': 'B4' })
Book.save({ '_key': 'B5', 'Name': 'B5' })
Author.save({ '_key': 'A', 'Name': 'A' })
Author.save({ '_key': 'B', 'Name': 'B' })
Author.save({ '_key': 'X', 'Name': 'X' })
Author.save({ '_key': 'Y', 'Name': 'Y' })
Author.save({ '_key': 'Z', 'Name': 'Z' })
User_Book.save({ '_from': 'User/001', '_to': 'Book/B1' })
User_Book.save({ '_from': 'User/001', '_to': 'Book/B2' })
User_Book.save({ '_from': 'User/001', '_to': 'Book/B3' })
User_Book.save({ '_from': 'User/001', '_to': 'Book/B4' })
User_Book.save({ '_from': 'User/001', '_to': 'Book/B5' })
Book_Author.save({ '_from': 'Book/B2', '_to': 'Author/A' })
Book_Author.save({ '_from': 'Book/B3', '_to': 'Author/B' })
Book_Author.save({ '_from': 'Book/B1', '_to': 'Author/X' })
Book_Author.save({ '_from': 'Book/B1', '_to': 'Author/Y' })
Book_Author.save({ '_from': 'Book/B1', '_to': 'Author/Z' })
const graph_module = require('org/arangodb/general-graph')
const graph = graph_module._create('LibraryGraph')
graph._addVertexCollection('User')
graph._addVertexCollection('Book')
graph._addVertexCollection('Author')
graph._extendEdgeDefinitions(graph_module._relation('User_Book', ['User'], ['Book']))
graph._extendEdgeDefinitions(graph_module._relation('Book_Author', ['Book'], ['Author']))
答案 0 :(得分:1)
我建议使用两次遍历,而不是使用具有可变深度(1..2)的单次遍历来覆盖两种情况,包含和不包含作者的书籍。
FOR book IN OUTBOUND "User/001" GRAPH "LibraryGraph"
LET author = FIRST(
FOR author IN OUTBOUND book._id GRAPH "LibraryGraph"
SORT author.Name
LIMIT 1
RETURN author.Name
) OR "\uFFFF"
SORT author
RETURN book
首先,我们从User/001
遍历到链接的书籍。然后我们从每本书到链接作者进行第二次遍历。这可能会返回0,1或多个作者。子查询将结果限制为按字母顺序排列的第一作者(例如X,X,Y,Z中的X)并返回名称。
在主查询的范围内,我们将作者姓名或后备值视为最后一个值,如果已排序(null
将首先结束,这里不需要)。然后我们按作者名称对书籍进行排序并返回:
实现这一结果的另一种方法,但更难理解:
FOR v, e, p IN 1..2 OUTBOUND "User/001" GRAPH "LibraryGraph"
LET name = p.vertices[2].Name OR "\uFFFF"
COLLECT book = p.vertices[1] AGGREGATE author = MIN(name)
SORT author
RETURN book
遍历返回带有2或3个顶点的路径......
[0] [1] [2]
User/001 --> Book/B2
User/001 --> Book/B2 --> Author/A
User/001 --> Book/B3
User/001 --> Book/B3 --> Author/B
User/001 --> Book/B4
User/001 --> Book/B5
User/001 --> Book/B1
User/001 --> Book/B1 --> Author/Y
User/001 --> Book/B1 --> Author/X
User/001 --> Book/B1 --> Author/Z
索引2(p.vertices[2]
)的作者或后备值暂时存储在变量name
中。然后将书籍顶点组合在一起以消除重复(由变量遍历深度引起,例如001-->B2
,但也返回更长的路径001-->B2-->A
)。
聚合用于选择具有最低值(MIN
)的作者姓名,这通常意味着按字母顺序排在第一位 - 然而,对于某些语言和字符集,它可能无法正常工作,而{{ 1}}根据设置语言的规则进行正确排序(每个DBMS实例只能有一个)。
分组结果 - 不同的图书文档 - 按作者姓名排序并返回。