You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tinkerpop.apache.org by Shay Nehmad <sh...@recolabs.ai> on 2021/02/14 12:28:10 UTC

Re: [DISCUSS] Creating pattern steps to codify best practices

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>
 >

Re: [DISCUSS] Creating pattern steps to codify best practices

Posted by Stephen Mallette <sp...@gmail.com>.
> Seems to me like adding "native" support for other property upsert flows
that aren't overwrite will be very useful.

i think we've discussed this sort of thing before, but I don't recall if it
was on this thread or not, but I do think it would help simplify certain
code. You rexamples demonstrate that. This might be a separate issue from
upsert() specifically though and more related to general update logic. If
you'd like to create an issue for it, then please feel free to do so (you
might check if it's already there though first).

On Sun, Feb 14, 2021 at 8:23 AM Shay Nehmad <sh...@recolabs.ai> wrote:

> 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>
>  >
>