2017-09-01 88 views
1

通过经松弛agheranimesh:根据用户书籍列表的第二邻居(作者)的属性排序直接邻居节点(书籍)?

这是我的图,命名为LibraryGraph

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

而是有可变深度(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最先结束,此处不需要)。然后我们按作者姓名的书籍进行排序,并返回他们:

Query result

另一种方式来实现这一结果,但很难理解:

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),这通常意味着作者的名字按字母顺序第一 - 它可能不适用于某些语言正确工作,但是字符集,而SORT不正确排序依据的设置语言的规则(每个DBMS实例只能有一个)。

分组结果 - 不同的书籍文档 - 按作者姓名排序并返回。