根据用户图书列表的二级邻居(作者)的属性对直接邻居节点(书籍)进行排序?
Sort direct neighbor nodes (books) by attribute of 2nd degree neighbors (authors) for user book list?
来自 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']))
我建议使用两次遍历,而不是使用具有可变深度 (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
遍历到链接的书籍。然后我们从每本书到链接的作者进行第二次遍历。这可能 return 0、1 或多个作者。子查询将结果限制为按字母顺序排列的第一作者(例如 X,Y,Z 中的 X)和 return 姓名。
在主查询的范围内,我们将作者姓名或回退到排序后最后的值(null
将最先结束,这在此处是不希望的)。然后我们按作者姓名和 return 对书籍进行排序:
实现此结果的另一种方法,但更难理解:
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
遍历 returns 条具有 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
中。然后将书的顶点组合在一起以消除重复项(由可变遍历深度引起,returns 例如 001-->B2
但也有更长的路径 001-->B2-->A
)。
聚合用于选择具有最低值的作者姓名 (MIN
),这通常意味着按字母顺序排在第一位 - 然而,它可能不适用于某些语言和字符集,而 SORT
确实根据设置语言的规则正确排序(每个 DBMS 实例只能是一个)。
分组结果 - 不同的书籍文档 - 按作者姓名和 returned 排序。
来自 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']))
我建议使用两次遍历,而不是使用具有可变深度 (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
遍历到链接的书籍。然后我们从每本书到链接的作者进行第二次遍历。这可能 return 0、1 或多个作者。子查询将结果限制为按字母顺序排列的第一作者(例如 X,Y,Z 中的 X)和 return 姓名。
在主查询的范围内,我们将作者姓名或回退到排序后最后的值(null
将最先结束,这在此处是不希望的)。然后我们按作者姓名和 return 对书籍进行排序:
实现此结果的另一种方法,但更难理解:
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
遍历 returns 条具有 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
中。然后将书的顶点组合在一起以消除重复项(由可变遍历深度引起,returns 例如 001-->B2
但也有更长的路径 001-->B2-->A
)。
聚合用于选择具有最低值的作者姓名 (MIN
),这通常意味着按字母顺序排在第一位 - 然而,它可能不适用于某些语言和字符集,而 SORT
确实根据设置语言的规则正确排序(每个 DBMS 实例只能是一个)。
分组结果 - 不同的书籍文档 - 按作者姓名和 returned 排序。