neomodel icon indicating copy to clipboard operation
neomodel copied to clipboard

Is there a way to bulk create or update relationships?

Open sojha05 opened this issue 3 years ago • 1 comments
trafficstars

I have seen through the documentation but couldnt find a way to bulk create or update just relationships. The connect function helps to create a single relationship only but is a lengthy and inefficient way.

sojha05 avatar Aug 24 '22 11:08 sojha05

Have you checked https://neomodel.readthedocs.io/en/latest/batch.html out?

rajeshyogeshwar avatar Sep 07 '22 09:09 rajeshyogeshwar

Hi! It is not clear to me how can the get_or_create function be used with the relationship parameter in order to create multiple relationships in batch. It seems to me that all the nodes specified in the function's parameter will be linked to the same relationship endpoint. Can you help me understand this usecase? Thanks @rajeshyogeshwar !

attilamester avatar Oct 14 '22 08:10 attilamester

Hello !

Looking at the code, the relationship argument is single and will apply to all elements in your tuple of nodes :

def get_or_create(cls, *props, **kwargs):
        lazy = kwargs.get("lazy", False)
        relationship = kwargs.get("relationship")

        # build merge query
        get_or_create_params = [
            {"create": cls.deflate(p, skip_empty=True)} for p in props
        ]
        query, params = cls._build_merge_query(
            get_or_create_params, relationship=relationship, lazy=lazy
        )

Is that a feature that you would still like to see ? Bulk create nodes and relationships at the same time ?

mariusconjeaud avatar Aug 04 '23 13:08 mariusconjeaud

From #639 :

I am trying to bulk create nodes and provide relationship along, the relationship gets created but without the properties. Although, it works fine if I am using connect method without explicitly defining the relationship properties details. Looking through the source code could find the below method is missing to pass the relation_properties to the _rel_helper function.

@classmethod
 def _build_merge_query(cls, merge_params, update_existing=False, lazy=False, relationship=None):
        query_params = dict(merge_params=merge_params)
        n_merge = "n:{0} {{{1}}}".format(
            ":".join(cls.inherited_labels()),
            ", ".join("{0}: params.create.{0}".format(getattr(cls, p).db_property or p) for p in cls.__required_properties__))
        if relationship is None:
            # create "simple" unwind query
            query = "UNWIND $merge_params as params\n MERGE ({0})\n ".format(n_merge)
        else:
            # validate relationship
            if not isinstance(relationship.source, StructuredNode):
                raise ValueError("relationship source [{0}] is not a StructuredNode".format(repr(relationship.source)))
            relation_type = relationship.definition.get('relation_type')
            if not relation_type:
                raise ValueError('No relation_type is specified on provided relationship')

            from .match import _rel_helper

            query_params["source_id"] = relationship.source.id
            query = "MATCH (source:{0}) WHERE ID(source) = $source_id\n ".format(relationship.source.__label__)
            query += "WITH source\n UNWIND $merge_params as params \n "
            query += "MERGE "
            query += _rel_helper(lhs='source', rhs=n_merge, ident=None,
                                 relation_type=relation_type, direction=relationship.definition['direction'])

@sojha05 Can you write test cases and what works and what doesn't ?

mariusconjeaud avatar Aug 04 '23 13:08 mariusconjeaud

Moving to #583

mariusconjeaud avatar Sep 26 '23 15:09 mariusconjeaud