0

I have a list of maps which correspond to records that I will receive in streaming, I need to take each record and upsert it.

I have seen many examples that work fine with just one vertex at a time, such that:

g.V('Amy').outE().where(inV().hasId('John')).
  fold().
  coalesce(
    unfold(),
    addE('manages').from(V('Amy')).to(V('John'))).
  property('duration', '1year')

Works just fine, my issue lies in the replication of those steps for each map inside the list.

I am currently using gremlin on Amazon Neptune Notebooks, if that makes any difference.

At the moment I am able to insert a record if it does not exist or just retreive it if it exists. Basically a "get or insert" functionality. How can I update each property of each record if it already exists?

My current query for the get or insert:

g.inject([['memshpnum':'13464406186','cmpcod':'LM','upddat':'2019-03-01 00:00:00','ccp_loaded_date':'2022-11-22T15:29:59.933Z','cusnum':'7531272','T.id': '7531272#ifl', 'T.label': 'ccp_node_customer', 'status': 'pend'],
    ['memshpnum':'00170674487','cmpcod':'LM','upddat':'2019-03-01 00:00:00','ccp_loaded_date':'2022-11-22T15:29:59.933Z','cusnum':'3076059','T.id': '3076059#ifl', 'T.label': 'ccp_node_customer'],
    ['memshpnum':'20203784496','cmpcod':'LM','upddat':'2019-04-01 00:00:00','ccp_loaded_date':'2022-11-22T15:29:59.933Z','cusnum':'3075659','T.id': '727745#ifl', 'T.label': 'ccp_node_customer'],
    ['memshpnum':'20203784498','cmpcod':'LM','upddat':'2019-04-01 00:00:00','ccp_loaded_date':'2022-11-22T15:29:59.933Z','cusnum':'3076058','T.id': '727365#ifl', 'T.label': 'ccp_node_customer']
]).unfold().as("properties").
  where(select("properties").unfold().filter(select(keys).is('T.label').or().is('T.cusnum')).select(values)).fold().
  coalesce(unfold(), 
      addV(select('properties').unfold().filter(select(keys).is('T.label')).select(values)).as("vertex").
      property(T.id, select('properties').unfold().filter(select(keys).is('T.id')).select(values)).
      sideEffect(select("properties").
         unfold().filter(select(keys).is(without('T.label','T.id'))).as("kv").
         select("vertex").
         property(select("kv").by(keys), select("kv").by(values))
    )
)

And amongst the things I have tried is this query:

g.inject([
    ['memshpnum':'13464406186','cmpcod':'LM','upddat':'2019-03-01 00:00:00','ccp_loaded_date':'2022-11-22T15:29:59.933Z','cusnum':'7531272','T.id': '7531272#ifl', 'T.label': 'ccp_node_customer', 'status': 'pend'],
    ['memshpnum':'00170674487','cmpcod':'LM','upddat':'2019-03-01 00:00:00','ccp_loaded_date':'2022-11-22T15:29:59.933Z','cusnum':'3076059','T.id': '3076059#ifl', 'T.label': 'ccp_node_customer'],
    ['memshpnum':'20203784496','cmpcod':'LM','upddat':'2019-04-01 00:00:00','ccp_loaded_date':'2022-11-22T15:29:59.933Z','cusnum':'3075659','T.id': '727745#ifl', 'T.label': 'ccp_node_customer'],
    ['memshpnum':'20203784498','cmpcod':'LM','upddat':'2019-04-01 00:00:00','ccp_loaded_date':'2022-11-22T15:29:59.933Z','cusnum':'3076058','T.id': '727365#ifl', 'T.label': 'ccp_node_customer']
]).unfold().as("properties").
  where(select("properties").unfold().filter(select(keys).is('T.label').or().is('T.cusnum')).select(values)).fold().
  coalesce(unfold()
           .property(select('properties').unfold().filter(select(keys).is(without('T.label','T.id'))).select(keys), select('properties').unfold().filter(select(keys).is(without('T.label','T.id'))).select(values)), 
      addV(select('properties').unfold().filter(select(keys).is('T.label')).select(values)).as("vertex").
      property(T.id, select('properties').unfold().filter(select(keys).is('T.id')).select(values)).
      sideEffect(select("properties").
         unfold().filter(select(keys).is(without('T.label','T.id'))).as("kv").
         select("vertex").
         property(select("kv").by(keys), select("kv").by(values))
    )
).toList()

However, I get an "Failed to interpret Gremlin query: The provided traverser does not map to a value" error.

  • Why do you need to check for the existence of a property before overwriting it? Vertex/Edge IDs are immutable but properties are mutable and can be overwritten or appended (when using single or set cardinality - `property(single,,)` ). You may also want to review https://stackoverflow.com/questions/73153821/multiple-add-if-doesnt-exist-steps-gremlin/73167871#73167871. Lastly, it is better to use withSideEffect() to inject a map vs inject in Neptune. inject() will cause the query to fall out of Neptune's query optimizer. – Taylor Riggan Jan 26 '23 at 12:55
  • I don't need to check for the existence of the property, but rather the existence of the node so that if the node already exists, I just update its properties, otherwhise I create a new node. And thank you for the sideEffect suggestion, I will definitely review it. – Diego Fontan Jan 26 '23 at 16:04

0 Answers0