I have a working js gremlin query for Haversine distance which I am looking to make more composable by setting constants for usage in the math step in some other way than using withSideEffect.
The necessity of creating the withSideEffect steps directly after g, the GraphTraversalSource, makes it difficult for me to write composable functions. In general, I've been chaining queries together by writing functions that take an existing GraphTraversal and return an extended GraphTraversal. Note that the commented out sideEffect traversal steps would solve my composability issue, but they do not work.
So: is there a function I can call on a GraphTraversal that lets me set constants for usage in math?
let query = this.g
.withSideEffect('rdeg', 0.017453293)
.withSideEffect('gcmiles', 3956)
.withSideEffect('sourceLat', lat)
.withSideEffect('sourceLng', lng)
.withSideEffect('radius', radius)
.V()
// .sideEffect('rdeg', 0.017453293)
// .sideEffect('gcmiles', 3956)
// .sideEffect('sourceLat', lat)
// .sideEffect('sourceLng', lng)
// .sideEffect('radius', radius)
.hasLabel('place')
.has('latitude')
.has('longitude')
.as('dst')
.where(
__.select('dst')
.by(__.project('lat', 'lon').by('latitude').by('longitude'))
.as('dstGrp')
.project('ladiff', 'lgdiff', 'lat1', 'lon1', 'lat2', 'lon2')
.by(
__.project('la1', 'la2')
.by(__.select('dstGrp').select('lat'))
.by(__.select('sourceLat'))
.math('(la2 - la1) * rdeg'),
)
.by(
__.project('lg1', 'lg2')
.by(__.select('dstGrp').select('lon'))
.by(__.select('sourceLng'))
.math('(lg2 - lg1) * rdeg'),
)
.by(__.select('dstGrp').select('lat'))
.by(__.select('dstGrp').select('lon'))
.by(__.select('sourceLat'))
.by(__.select('sourceLng'))
.math('(sin(ladiff/2))^2 + cos(lat1*rdeg) * cos(lat2*rdeg) * (sin(lgdiff/2))^2')
.math('gcmiles * (2 * asin(sqrt(_)))')
.is(gremlin.process.P.lt(radius)),
);
I would like to be able to write something that looks like this, using the function excerpted above:
let placesQuery = this.g
.V(userId)
.out('IS_FRIENDS_WITH')
.union(__.out('IS_INTERESTED_IN'), __.out('BOOKMARKED'))
.hasLabel('place')
.not(__.or(__.in_('IS_INTERESTED_IN').hasId(userId), __.in_('BOOKMARKED').hasId(userId)));
placesQuery = this.withinHaversineDistanceWithBoundingBoxQuery(placesQuery);