I'd like to expand on our use case. In our case, some property upsert
logic is rather complex - not just an overwrite. We're using the Python
language variant, so the examples are Pythonic.
For different properties, we need different property upsert logic. For
example, we have a property that indicates duration. If it already
exists, we don't want to just overwrite, we want to sum the values. We
use the following code:
```
traversal_to_append_to.property(prop_name, union(values(prop_name),
constant(int(prop_value))).sum())
```
We have similar use cases for min and max as well.
We also have use cases in which one property depends on another. For
example, we want to update the "name" property only if the "update_time"
property is bigger than what exists:
```
traversal_to_append_to.as_("original_traversal").choose(
values(self.time_prop_name).is_(P.gt(current_log_time)),
__.select("original_traversal"),
__.select("original_traversal").property(prop_name,
prop_value),
)
```
Seems to me like adding "native" support for other property upsert flows
that aren't overwrite will be very useful. I imagine the interface could
look something like
// match on id, then sum duration
g.upsertV('person', [(T.id): 100, name:'marko']).by(T.id).
property('duration',100,PropertySum)
We've developed an external infrastructure (in our closed-source
product) that solves this for us, and I'd love to expand on all the use
cases we have if that's relevant.
(I probably won't be checking this thread super often but I can be
reached via email or Twitter @ShayNehmad)
On 2020/09/17 01:25:41, David Bechberger wrote:
> I've had a few on and off discussions with a few people here, so I
wanted>
> to send this out to everyone for feedback.>
>
> What are people's thoughts on creating a new set of steps that codify>
> common Gremlin best practices?>
>
> I think there are several common Gremlin patterns where users would
benefit>
> from the additional guidance that these codified steps represent. The>
> first one I would recommend though is codifying the element existence>
> pattern into a single Gremlin step, something like:>
>
> mergeV(String, Map, Map)>
> String - The vertex label>
> Map (first) - The properties to match existing vertices on>
> Map (second) - Any additional properties to set if a new vertex is>
> created (optional)>
> mergeE(String, Map, Map)>
> String - The edge label>
> Map (first) - The properties to match existing edge on>
> Map (second) - Any additional properties to set if a new edge is>
> created (optional)>
>
> In each of these cases these steps would perform the same upsert>
> functionality as the element existence pattern.>
>
> Example:>
>
> g.V().has('person','name','stephen').>
> fold().>
> coalesce(unfold(),>
> addV('person').>
> property('name','stephen').>
> property('age',34))>
>
> would become:>
>
> g.mergeV('person', {'name': 'stephen'}, {'age', 34})>
>
> I think that this change would be a good addition to the language for>
> several reasons:>
>
> * This codifies the best practice for a specific action/recipe, which>
> reduces the chance that someone uses the pattern incorrectly>
> * Most complex Gremlin traversals are verbose. Reducing the amount of
code>
> that needs to be written and maintained allows for a better developer>
> experience.>
> * It will lower the bar of entry for a developer by making these
actions>
> more discoverable. The more we can help bring these patterns to the>
> forefront of the language via these pattern/meta steps the more we
guide>
> users towards writing better Gremlin faster>
> * This allows DB vendors to optimize for this pattern>
>
> I know that this would likely be the first step in Gremlin that
codifies a>
> pattern, so I'd like to get other's thoughts on this?>
>
> Dave>
>