cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

How can I pass a node or relationship to a inner apoc call?

Guys,

I am trying to implement a 'edit function' on my web application, but I having a hard time trying to figure out how to pass my node and relationship to a inner apoc.refactor.to call.

My query is as follows:

WITH
  'mas_muovebrasil'          as pTenantName,
  87                         as pOrgId,
  'Teste edição instituição' as pOrgName,
  '111'                      as pOrgCNPJ,
  'outro'                    as pOrgKindAutoname,
  'Grupo de amigos'          as pOrgKindDetail
MATCH
  (t:TenantMAS)<-[rel_seen:as_seen_by]-(org:Organization)-[rel_class:is_classified_as]->(old_class:OrganizationKind),
  (new_class:OrganizationKind)
WHERE
  t.name = pTenantName
  and org.id = pOrgId
  and new_class.auto_name = pOrgKindAutoname
SET
  org.name = pOrgName,
  org.cnpj = pOrgCNPJ,
  rel_class.specific_classification = pOrgKindDetail
WITH
  t,
  rel_seen,
  org,
  rel_class,
  old_class,
  new_class
CALL apoc.do.when(
  old_class <> new_class,
  'CALL apoc.refactor.to(rel, toNode) YIELD input, output',
  '',
  '{rel: rel_class, toNode: new_class}'
) YIELD value
RETURN *

I am getting the following error:

Neo.ClientError.Statement.SyntaxError: Type mismatch: expected Map, Node or Relationship but was String

Should I "capture" the node and the relationship in the apoc.do.when right before the call apoc.reafactor.to or is there a way of passing it along to the inner call?

Thanks in advance,

1 ACCEPTED SOLUTION

Guys,

I think I just spotted two single quotation marks where they should not have been.

Sorry for my mistake. Let's see if I advance with that.

Thanks

View solution in original post

9 REPLIES 9

Guys,

I think I just spotted two single quotation marks where they should not have been.

Sorry for my mistake. Let's see if I advance with that.

Thanks

Yes, well spotted.
You should also use parameters on the outside query and not a WITH with literal values

You are right, Michael!

We cannot do this at the moment because we are connecting to two neo4j instances, one through a ruby gem and the other through the http endpoint (the one related to this query).

We have plans on phasing out one of the instances and using the gem and the BOLT protocol for the remaining. Then, we will do things more properly regarding this matter...

Unless you tell me I can do this right now with the HTTP endpoint! (I did not find anything related to this on my researches.

The ruby gem and http endpoints all support query parameters.

That's really nice! I thought they were exclusive of the BOLT protocol.

If you allow me one more question, I would like to know how to proper implement this.

If I am not mistaken, I have to make one call setting the parameters, one with the query itself and another one "cleaning after myself". Is this right?

Currently I just have to make one call, although I know I have the downside of "forcing" Neo4j to always "hard parse" my queries...

Any documentation regarding my doubts will be highly appreciated!

Thanks in advance,

Not really sure what you mean? Do you have a concrete example?

Can't you pass the parameter hash to both in the client?

Michael, let me try with the query:

WITH
  'mas_muovebrasil'            as pTenantName,
  101                          as pAgentId,
  'Alameda Franca'             as pActAddrStreetName,
  '406'                        as pActAddrNumber,
  'Jardins'                    as pActAddrNeighborhood,
  '00000-000'                  as pActAddrPostalCode,
   0.0                         as pActAddrLatitude,
   0.0                         as pActAddrLongitude,
  'sao-paulo-sp'               as pActAddrCity
MATCH
  (c:City {normalized_name: pActAddrCity}),
  (:TenantMAS {name: pTenantName})<-[:as_seen_by]-(:LocalAgent {id: pAgentId})-[:exercises]->(i:Influence)
MERGE
  (new_addr:Address {
    street_name:  pActAddrStreetName,
    number:       pActAddrNumber,
    neighborhood: pActAddrNeighborhood,
    cep:          pActAddrPostalCode
  })-[:belongs_to]->(c)
ON CREATE SET
  new_addr.latitude  = pActAddrLatitude,
  new_addr.longitude = pActAddrLongitude
WITH
  i,
  new_addr
MATCH
  (i)-[rel_sup:supported_on]->(old_addr:Address)
WITH
  rel_sup,
  old_addr,
  new_addr
CALL apoc.do.when(
  old_addr <> new_addr,
  'CALL apoc.refactor.to(rel_to_change, toNode) YIELD input, output, error RETURN error',
  '',
  {rel_to_change: rel_sup, toNode: new_addr}
) YIELD value
RETURN
  new_addr

(please, don't mind the absence of parameters. I will fix this eventually)

I want to be able to plot my graph in both situations, either when it gets refactored or not, but I was not able to achieve this properly...

Thanks!

You probably don't want to return the error but the new relationship
and in the else branch return the existing relationship?

Maybe I didn't do it properly, but I tried exactly this before.

It was then that I tried to understand the "meaning" of the output values of the APOC procedures...

I will look into this again when I rewrite this query to use parameters.

Thanks,