Group vertices followed by Order and Retrieving them

47 Views Asked by At

I am very new to gremlin and currently am doing a proof of concept on Azure CosmosDB. My graph looks like this:

Add vertices of type object1:

g.addV(‘object1’).property('id','1').addV(‘object1’).property('id’,’2’)

Add vertices of type object2:

g.addV(‘object2’).property('id','1').property(‘date’, ’01-08–2023’).property(‘type’, ’ordinary’).property(’object1’, ’1’)
.addV(‘object2’).property('id’, ’2’).property(‘date’, ’02-08–2023’).property(‘type’, ’special’).property(,’object1’, ‘1’)
.addV(‘object2’).property('id’, ’3’).property(‘date’, ’31-07–2023’).property(‘type’, ’ordinary’).property(’object1’, ‘1’)

.addV(‘object2’).property('id’,’4’).property(‘date’, ’01-07–2023’).property(‘type’, ’ordinary’).property(’object1’, ‘2’)
.addV(‘object2’).property('id’,’5’).property(‘date’, ’02-07–2023’).property(‘type’, ’special’).property(’object1’, ‘2’)
.addV(‘object2’).property('id’,’6’).property(‘date’, ’30-06–2023’).property(‘type’, ’ordinary’).property(’object1’, ‘2’)

Add relations between object2 and object1:

g.V().hasLabel(‘object1’).has('id', '1').addE('SCANNED').from(g.V().hasLabel(‘object2’).has('id', '1')).inV().addE('SCANNED').from(g.V().hasLabel(‘object2’).has('id', '2').from(g.V().hasLabel(‘object2’).has('id', ‘3’)

g.V().hasLabel(‘object1’).has('id', ‘2’).addE('SCANNED').from(g.V().hasLabel(‘object2’).has('id', ‘4’)).inV().addE('SCANNED').from(g.V().hasLabel(‘object2’).has('id', ‘5’).from(g.V().hasLabel(‘object2’).has('id', ‘6’)

As seen:

object2 vertices having ids [1,2,3] —SCANNED—> object1 [id:1]
object2 vertices having ids [4,5,6] —SCANNED—> object1 [id:2]

What I need is:

For each object1:

  1. find out the latest object2 having type “ordinary”
  2. then, find out the latest object2 having type “special” (which is also later than the object2 in step 1)
  3. Collect these object2 vertices from step1 and step2

So the output should be: [object2 id:1, object2 id:2, object2 id:4, object2 id:5]

Object2 will have other relations which will be traversed once the output in the above form is obtained.

What I have tried is the grouping by, that works:

g.V().hasLabel(“object1”).in(“SCANNED”).group().by(“object1”)


Then it gets grouped by neatly per object 1 i.e

[
{
1: [
      { ‘id’ : ‘1’, ‘date’: ’01-08-2023’, ‘type’: ‘ordinary’, “object1”: ‘1’},
      { ‘id’ : ‘2’, ‘date’: ’02-08-2023’, ‘type’: ‘ordinary’, “object1”: ‘1’},
      { ‘id’ : ‘3’, ‘date’: ’31-07-2023’, ‘type’: ‘ordinary’, “object1”: ‘1’}
],
2:[
     { ‘id’ : ‘4’, ‘date’: ’01-07-2023’, ‘type’: ‘ordinary’, “object1”: ‘2’},
     { ‘id’ : ‘5’, ‘date’: ’02-07-2023’, ‘type’: ‘ordinary’, “object1”: ‘2’},
     { ‘id’ : ‘6’, ‘date’: ’30-06-2023’, ‘type’: ‘ordinary’, “object1”: ‘2’}
]
}
]

Now, for both object1s:

  1. How do I order the object2s to get the latest of type ordinary?
  2. How do I get the latest object2 of type special that comes later than the object2 in step1 ?
  3. Retrieve these object2s so that it can be used for further traversal ?
1

There are 1 best solutions below

0
ajj On

I was able to do this by the following approach:

g.V().hasLabel("object1") => (1)
.flatmap( -> (2)
__.as("obj1").in("SCANNED") => (3)
.has("type","ordinary")
.order().by("date",decr)
.limit(1)
.as("_scan") => (4)
.coalesce( => (5)
select("_obj1").in("SCANNED")
.has("type","special")
.as("_obj2")
.where("_obj2",gte("_scan")).by("date"),select("_scan"))
.as("_scan") => (6)
.select(all, "_scan") => 7
.unfold()).<continue further with the filtered vertices>

###Explanation:###

  1. Loop through object1 vertices
  2. In the loop, store the incoming object1 into 'obj1', traverse through its incoming relations "SCANNED" and get to the connected object_2s
  3. Order the object_2s of type ordinary by date, to get the latest one
  4. Store it in '_scan'
  5. Go to the starting point i.e object_1 stored in obj1 and traverse through the incoming relation "SCANNED" to get to the connected object_2s. Get the object_2 of type 'special' and compare it against the object_2 that was obtained in step 3, based on the date.
  6. Store it in '_scan'.
  7. Select all the '_scan' to get the object_1 of types 'ordinary' and 'special'. Unfold it to get the vertices of object_1 that were filtered