Search code examples
azure-cosmosdbgremlingraph-databasesazure-cosmosdb-gremlinapi

Include a specific edge from a parent vertex in traversal


Graph Database

The image above is a representation of my graph database from Azure Cosmos DB.

I need to fetch the addresses with products that are projected with product properties, detail vertices linked to product from address vertex and the properties of produces edge.

This is the query that i came up with, but it does not include the properties of produces edge with the product.

g.V()
.hasLabel('address')
.project('address', 'products')
.by(valueMap(true))
.by(
    __.as('a')
    .outE('produces')
    .as('details1')
    .select('a')
    .out()
    .hasLabel('detail')
    .as('d')
    .out()
    .hasLabel('product')
    .group()
    .by(valueMap(true))
    .by(select('d').dedup().valueMap(true).fold())
    .unfold()
    .project('product', 'custom_details', 'details')
    .by(select(keys))
    .by(select(values))
    .by(select('details1').valueMap(true).fold())
    .fold()
)

Seeding graph:

g
.addV('address')
.property('name', 'address1')
.property('id', 'address1')
.property('pk', 'address1')
.as('address1')

.addV('address')
.property('name', 'address2')
.property('id', 'address2')
.property('pk', 'address2')
.as('address2')

.addV('detail')
.property('name', 'detail1')
.property('id', 'detail1')
.property('pk', 'detail1')
.as('detail1')

.addV('detail')
.property('name', 'detail2')
.property('id', 'detail2')
.property('pk', 'detail2')
.as('detail2')

.addV('detail')
.property('name', 'detail3')
.property('id', 'detail3')
.property('pk', 'detail3')
.as('detail3')

.addV('detail')
.property('name', 'detail4')
.property('id', 'detail4')
.property('pk', 'detail4')
.as('detail4')

.addV('product')
.property('name', 'product1')
.property('id', 'product1')
.property('pk', 'product1')
.as('product1')

.addV('product')
.property('name', 'product2')
.property('id', 'product2')
.property('pk', 'product2')
.as('product2')

.addE('produces')
.from('address1')
.to('product1')

.addE('produces')
.from('address2')
.to('product1')

.addE('produces')
.from('address2')
.to('product2')

.addE('product_detail')
.from('address1')
.to('detail1')

.addE('product_detail')
.from('detail1')
.to('product1')

.addE('product_detail')
.from('address1')
.to('detail2')

.addE('product_detail')
.from('detail2')
.to('product1')

.addE('product_detail')
.from('address2')
.to('detail3')

.addE('product_detail')
.from('detail3')
.to('product1')

.addE('product_detail')
.from('address2')
.to('detail4')

.addE('product_detail')
.from('detail4')
.to('product2')

Solution

  • If I understood the required result from your query, I think you looking for something like that:

    g.V().hasLabel('address').
      project('address', 'products').
        by(valueMap(true)).
        by(__.as('a').
          outE('produces').
          project('product', 'custom_details', 'details').
            by(inV().valueMap(true)).
            by(inV().in('product_detail').
                where(__.in('product_detail').as('a')).
                valueMap(true).fold()).
            by(valueMap(true)).fold())
    

    example: https://gremlify.com/8s