title: Improve relationship performance using Spring Data Neo4J
body: <p>We are using Spring Boot 2.2.5 and Spring Data Neo4J. We have nodes with relationships which we have mapped with Spring NodeEntity and RelationshipEntity. What we are noticing is if there are nodes with lots of first level relationships (e.g. over 1500), its taking time (over 1 second) to get and update the entity/relationships.</p>
  
  <p>Are there any best practices on how to improve performance for the relationships. Are there ways we can use pagination, limits etc.?</p>
  
  <p>Code: </p>
  
  <pre><code>@NodeEntity
  public class Node {
  
      @Id
      @GeneratedValue
      private Long id;
  
      private String name;
  
      @Relationship(type = RelatedNode.TYPE, direction = Relationship.UNDIRECTED)
      private Set&lt;RelatedNode&gt; relatedNodes = new HashSet&lt;&gt;();
  
      public Long getId() {
          return id;
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public Set&lt;RelatedNode&gt; getRelatedNodes() {
          return relatedNodes;
      }
  
      public void setRelatedNodes(Set&lt;RelatedNode&gt; relatedNodes) {
          this.relatedNodes = relatedNodes;
      }
  
      public RelatedNode addRelatedNode(Node relatedNode, long count) {
          final RelatedNode node = this.relatedNodes.stream()
          .filter(i -&gt; (relatedNode.getId().equals(i.getEnd().getId())) || (relatedNode.getId().equals(i.getStart().getId())))
              .findFirst()
              .orElseGet(() -&gt; {
                  RelatedNode newRelatedNode = new RelatedNode();
                  newRelatedNode.setStart(this);
                  newRelatedNode.setEnd(relatedNode);
                  newRelatedNode.setCount(count);
                  this.relatedNodes.add(newRelatedNode);
                  return newRelatedNode;
              });
          return node;
      }
  
      public RelatedNode updateRelatedNode(Node relatedNode, long count) {
          final RelatedNode node = this.relatedNodes.stream()
          .filter(i -&gt; (relatedNode.getId().equals(i.getEnd().getId())) || (relatedNode.getId().equals(i.getStart().getId())))
              .findFirst().get();
          if (node != null) {
              node.setCount(count);
          }
          return node;
      }
  
      public void deleteRelatedNode(Node relatedNode) {
          final RelatedNode node = this.relatedNodes.stream()
              .filter(i -&gt; (relatedNode.getId().equals(i.getEnd().getId())) || (relatedNode.getId().equals(i.getStart().getId())))
              .findFirst().get();
          this.relatedNodes.remove(node);
      }
  }
  
  @RelationshipEntity(type = RelatedNode.TYPE)
  public class RelatedNode {
  
      public static final String TYPE = "RELATED_TO";
  
      @Id
      @GeneratedValue
      private Long id;
  
      @StartNode
      private Node start;
  
      @EndNode
      private Node end;
  
      private long count;
  
      public Long getId() {
          return id;
      }
  
      public long getCount() {
          return count;
      }
  
      public void setCount(long count) {
          this.count = count;
      }
  
      public Node getEnd() {
          return end;
      }
  
      public void setEnd(Node end) {
          this.end = end;
      }
  
      public Node getStart() {
          return start;
      }
  
      public void setStart(Node start) {
          this.start = start;
      }
  
      public void setId(Long id) {
          this.id = id;
      }    
  }
  </code></pre>
  
  <p>Notes:
  I am having to add/update related nodes by using addRelatedNode/updateRelatedNode methods. If I create/update relationships without these methods, the relationships are duplicated as the relationship entity has attributes.</p>