For step:
has(<property>, without(<value_0>, <value_1>, ...))
<value_i> are a treated as a scalar values to filter <property> on. In Cosmos DB, this resolves to an index-lookup filter: <properykey> not in (<value_0>, <value_1>, ...).
So has(id, without('idList')) won't apply the filter as you are expecting, as it won't resolve 'idList' as a variable reference.
For step:
the <key> parameter is treated as a reference to a side-effect, map, path label, so in this case it will resolve 'idList'
In Cosmos DB, where(...) expressions compile to runtime evaluated filters in most cases. A few cases can optimize to index filters, but not for the examples you provided.
In the case of runtime evaluation, results from the preceding operators are streamed to the where filter for evaluation, so additional intermediate GetEdge results will be enumerated as shown in the execution profile.
Given this, there isn't an alternative traversal that will perform more efficiently in Cosmos DB.
However, you could improve the efficiency by breaking the operation into multiple requests.
So for this traversal:
g.V().has(id, 1).outE("created").store("edgeList").inV().inE().where(without("edgeList"))
Instead of reading streaming inE() results to apply the where() filter, this could be split into two traversals:
- Resolves the outE() edges
- Resolves the set of inE() edges not included in the outE() results.
For example:
gremlin> g.V().has(id, '1').outE('created')