Reputation: 81
I’m using Gremlin for querying a Graph DB and I’m having trouble figuring out how to retrieve all properties of a specific vertex along with all properties of specific child vertices. I know valueMap()
is generally the operation to use to expose properties of nodes, but I'm not sure I am using it correctly.
Here is a visual representation of the Graph that I am working with. In this graph there are author
nodes, which can be related to multiple book
nodes connected by a wrote
edge. And a book
node can be connected to multiple chapter nodes by a hasChapter
edge. A book
node has a title and year as additional properties, while a chapter
node has a name and a length as additional properties:
Here is the data that produces the above graph:
g.addV('author').property(id, 'author1').as('a1').
addV('book').
property(id,'book1').
property('title', 'Book 1').
property('year', '1999').
as('b1').
addV('book').
property(id,'book2').
property('title', 'Book 2').
property('year', '2000').
as('b2').
addV('book').
property(id,'book3').
property('title', 'Book 3').
property('year', '2002').
as('b3').
addE('wrote').from('a1').to('b1').
addE('wrote').from('a1').to('b2').
addE('wrote').from('a1').to('b3').
addV('chapter').
property(id,'b1chapter1').
property('name', 'The Start').
property('length', '350').
as('b1c1').
addV('chapter').
property(id,'b1chapter2').
property('name', 'Trees').
property('length', '500').
as('b1c2').
addV('chapter').
property(id,'b2chapter1').
property('name', 'Chapter 1').
property('length', '425').
as('b2c1').
addV('chapter').
property(id,'b2chapter2').
property('name', 'Chapter 2').
property('length', '650').
as('b2c2').
addV('chapter').
property(id,'b2chapter3').
property('name', 'Chapter 3').
property('length', '505').
as('b2c3').
addE('hasChapter').from('b1').to('b1c1').
addE('hasChapter').from('b1').to('b1c2').
addE('hasChapter').from('b2').to('b2c1').
addE('hasChapter').from('b2').to('b2c2').
addE('hasChapter').from('b2').to('b2c3').
iterate()
I would like to form a query that is able to return the properties of all books that are written by author1
, along with all properties of each book’s chapters, ideally sorted by date (ascending). I'm wondering if it's possible to make a query that would return the results in the following fashion (or something similar enough that I can parse through on the client side):
1 {'year': ['1999'], 'title': ['Book 1'], 'chapters': [{'name': ['The Start'], 'length': ['350']}, {'name': ['Trees'], 'length': ['500']}]}
2 {'year': ['2000'], 'title': ['Book 2'], 'chapters': [{'name': ['Chapter 1'], 'length': ['425']}, {'name': ['Chapter 2'], 'length': ['650']}, {'name': ['Chapter 3'], 'length': ['505']}]}
3 {'year': ['2002'], 'title': ['Book 3'], 'chapters': []}
So far, I have attempted a few variations of this query with no luck:
g.V('author1').as('writer')
.out('wrote').as('written')
.order().by('year', asc)
.out('hasChapter').as('chapter')
.project('written', 'chapter')
.by(valueMap())
which returns:
1 {'written': {'name': ['The Start'], 'length': ['350']}, 'chapter': {'name': ['The Start'], 'length': ['350']}}
2 {'written': {'name': ['Trees'], 'length': ['500']}, 'chapter': {'name': ['Trees'], 'length': ['500']}}
3 {'written': {'name': ['Chapter 1'], 'length': ['425']}, 'chapter': {'name': ['Chapter 1'], 'length': ['425']}}
4 {'written': {'name': ['Chapter 2'], 'length': ['650']}, 'chapter': {'name': ['Chapter 2'], 'length': ['650']}}
5 {'written': {'name': ['Chapter 3'], 'length': ['505']}, 'chapter': {'name': ['Chapter 3'], 'length': ['505']}}
The above query only returns the chapter properties for all books with chapters, whereas I'm looking for a query that will give me all book
properties (regardless of whether the book has chapters) and all chapter
properties of each book. Anyone have any advice on the use of valueMap()
across multiple levels of traversal. Ideally would like to avoid multiple queries to the Graph DB, but open to solutions that involve doing so.
Upvotes: 1
Views: 276
Reputation: 877
This below query gives the result exactly as you needed. I think the key is projecting the values inside the by modulator.
gremlin> g.V('author1').
......1> out('wrote').
......2> order().by('year', asc).
......3> project('year', 'title', 'chapters').
......4> by('year').
......5> by('title').
......6> by(out('hasChapter').valueMap().fold())
==>[year:1999,title:Book 1,chapters:[[name:[Trees],length:[500]],[name:[The Start],length:[350]]]]
==>[year:2000,title:Book 2,chapters:[[name:[Chapter 1],length:[425]],[name:[Chapter 2],length:[650]],[name:[Chapter 3],length:[505]]]]
==>[year:2002,title:Book 3,chapters:[]]
Upvotes: 1