Confusing behavior of `select()`.

The following traversal acts as a counter:
g.withSideEffect("map", [3: "foo", 4: "bar"]).
inject("a", "b", "c", "d").
aggregate(local, "x").
map(select("x").count(local))
g.withSideEffect("map", [3: "foo", 4: "bar"]).
inject("a", "b", "c", "d").
aggregate(local, "x").
map(select("x").count(local))
It produces:
==>1
==>2
==>3
==>4
==>1
==>2
==>3
==>4
I want to modify the traversal to use this count to produce ["foo", "bar"]. So, I tried adding .as("cnt").select("map").select(select("cnt")) like this:
g.withSideEffect("map", [3: "foo", 4: "bar"]).
inject("a", "b", "c", "d").
aggregate(local, "x").
map(select("x").count(local)).
as("cnt").
select("map").select(select('cnt'))
g.withSideEffect("map", [3: "foo", 4: "bar"]).
inject("a", "b", "c", "d").
aggregate(local, "x").
map(select("x").count(local)).
as("cnt").
select("map").select(select('cnt'))
But the code above does not work as expected, it produces no output. Interestingly, if I change select("cnt") to constant(3), then it starts producing foo:
==>foo
==>foo
==>foo
==>foo
==>foo
==>foo
==>foo
==>foo
Could someone help me understand why select("cnt") is not working here and why using constant(3) works? Thanks in advance!
Solution:
This is caused (if you are using TinkerGraph for example) by Java's HashMap implementation and the fact that a Long will not match an Integer type. ``` g.withSideEffect("map", [3L: "foo", 4L: "bar"]). inject("a", "b", "c", "d"). aggregate(local, "x")....
Jump to solution
7 Replies
triggan
triggan3w ago
This might be where you need to use a where()-by()-by() pattern.
g.withSideEffect("map", [3: "foo", 4: "bar"]).
inject("a", "b", "c", "d").
aggregate(local, "x").
map(select("x").count(local)).as('cnt').
select('map').unfold().select(values).
where('map',eq('cnt')).by(unfold().select(keys)).by()
g.withSideEffect("map", [3: "foo", 4: "bar"]).
inject("a", "b", "c", "d").
aggregate(local, "x").
map(select("x").count(local)).as('cnt').
select('map').unfold().select(values).
where('map',eq('cnt')).by(unfold().select(keys)).by()
==> foo
==> bar
==> foo
==> bar
I don't recall what the issue is with select(select(somekey))
Solution
kelvinl2816
kelvinl28163w ago
This is caused (if you are using TinkerGraph for example) by Java's HashMap implementation and the fact that a Long will not match an Integer type.
g.withSideEffect("map", [3L: "foo", 4L: "bar"]).
inject("a", "b", "c", "d").
aggregate(local, "x").
map(select("x").count(local)).
as("cnt").
select("map").select(select('cnt'))

==>foo
==>bar
g.withSideEffect("map", [3L: "foo", 4L: "bar"]).
inject("a", "b", "c", "d").
aggregate(local, "x").
map(select("x").count(local)).
as("cnt").
select("map").select(select('cnt'))

==>foo
==>bar
kelvinl2816
kelvinl28163w ago
"cnt" is going to be a Long. By making the map keys explicit Long values, it works (as Long#equals will be true as far as the HashMap is concerned).
Max
Max3w ago
Interesting pattern, thank you! This seems like undocumented feature of where() step. Making map keys explicit Long values does work for this example. But the actual map in my code is generated dynamically by the group().by("someIntegerProp") step. This means that someIntegerProp has to be created as Long value in the first place, am I correct? I am using JavaScript GLV by the way, and I found toLong function there. I will try it. Thank you!
triggan
triggan3w ago
Kelvin has this documented in Practical Gremlin, though. Given the flexibility of the Gremlin language, likely difficult to have every possible pattern documented in one place. https://kelvinlawrence.net/book/Gremlin-Graph-Guide.html#whereby
No description
Max
Max2w ago
I have encountered another issue related to numeric types. If keys in a Map end up being of type Double (for example as the result of math()...group() steps), I couldn't find a way to access the map by key. I am using TypeScript/JavaScript GLV, and the incoming traverser produces values that have Long type, but the map keys have Double type. How can I access the map by key, given this situation?
spmallette
spmallette2w ago
there is a trick for select() which i think i almost like as a trick more than if we made select() take any input: g.inject(1.0, 2.0, 3.0, 3.0).group().select(constant(3.0))
Want results from more Discord servers?
Add your server