6 Replies Latest reply on Jul 22, 2013 9:30 AM by fazileh

    Order of child nodes

    bwallis42

      If I add two child nodes, is there a way I can control the order at the time of adding or do I have to rearrange afterwards. As far as I can tell addNode() always adds to the start of the list.

       

      {code}

                  Node section = patientNode.addNode("inf:section", "inf:section");

      // if I print the path, inf:section is at index 1 (ie: no index), ".../inf:section"

                  Node section2 = patientNode.addNode("inf:section", "inf:section");

      // if I print the path for the first section it is now at index 2 ie: ".../inf:section[2]"

      // so the path for section has changed once section2 was added.

      // the path for section2 is ".../inf:section" which was the path of section.

       

      // I can get the opposite order by calling orderBefore

                  patientNode.orderBefore("inf:section[2]", "inf:section[1]");

       

      {code}

       

      Is this all I can do to get the desired order? (I could insert in the opposite order of course)

       

      It isn't really all that important, not sure I want to rely on maintaining node order in my model anyway.

       

      It is just that I found the behaviour of addNode() adding to the start of the list of child nodes surprising

       

      (version 2.7.0)

        • 1. Re: Order of child nodes
          rhauch

          If I add two child nodes, is there a way I can control the order at the time of adding or do I have to rearrange afterwards. As far as I can tell addNode() always adds to the start of the list.

          New nodes should always appear at the end of the list of children (I just verified this), and if you want a different order you will have to either leverage the order of adding nodes or use 'orderBefore(...)'. Unfortunately, the JCR API doesn't provide an alternative.

           

          BTW, I just verified that nodes are added to the end of the list of children, using this code:

           

           

                  Node root = session.getRootNode();
                  root.addNode("node1", testNodeType);
                  root.addNode("node2", testNodeType);
                  root.addNode("node3", testNodeType);
                  session.save();
          
                  root.addNode("node4", testNodeType);
                  root.addNode("node5", testNodeType);
                  root.addNode("node6", testNodeType);
                  session.save();
          
                  NodeIterator iter = root.getNodes();
                  while (iter.hasNext()) {
                      System.out.println(iter.nextNode());
                  }
          
          

           

          The result was this:

           

           

          /node1 {jcr:primaryType=nt:unstructured, }
          /node2 {jcr:primaryType=nt:unstructured, }
          /node3 {jcr:primaryType=nt:unstructured, }
          /node4 {jcr:primaryType=nt:unstructured, }
          /node5 {jcr:primaryType=nt:unstructured, }
          /node6 {jcr:primaryType=nt:unstructured, }
          /jcr:system {jcr:primaryType=mode:system, }
          
          

           

          The "jcr:system" child of the root node is the one exception to this rule -- it always appears at the end of the root node's list of children.

          • 2. Re: Order of child nodes
            bwallis42

            Thanks. I should have written the simple case myself, I just believed the test case I was writing and there was another error in the code that caused what I was seeing.

             

            My case was a little different in that the definition of the child nodes I was inserting was like

             

             

            {code}

            [local:A] orderable

            + local:b (local:B) multiple

             

            [local:B]

            {code}

             

            but the insert order is the same, to the end of the list of nodes.

             

            Thanks, sorry to waste your time.

             

            brian...

            • 3. Re: Order of child nodes
              rhauch

              No worries! Glad I could help.

              • 4. Re: Order of child nodes
                fazileh

                Hi, Excuse me,

                I was looking for  "get sorted nodes by a condition", I saw this post.

                Would you please help me how to get sorted node list by descending order.

                 

                Thank you.

                • 5. Re: Order of child nodes
                  hchiorean

                  The JCR spec doesn't provide a way to get nodes in reverse order out-of-the-box (see the above answer "New nodes should always appear at the end of the list of children (I just verified this), and if you want a different order you will have to either leverage the order of adding nodes or use 'orderBefore(...)'. Unfortunately, the JCR API doesn't provide an alternative")

                   

                  This means that to get this behavior, you need to explicitly code for it. I can think of a couple of options:

                  • retrieve the nodes via parent.getNodes() and iterate & reverse the list of nodes
                  • design the node types of your child nodes in such a way that you're able to query for child nodes using ORDER BY DESC. For example, if you add the [mix:created] mixin to each child node, the repository will auto-set the jcr:created (date) property when a child is created. This means that you should be able to retrieve the reverse list of children (newest to oldest) by using a SELECT ... ORDER BY [jcr:created] DESC type query.

                   

                  It depends on the context, but normally using queries is slower (performance-wise) than performing in-memory operations.

                  • 6. Re: Order of child nodes
                    fazileh

                    Thanks a lot for reply and nice explanations. It was useful for me. 

                    I will use the first method : " parent.getNodes() and iterate & reverse the list of nodes" couse it's faster as you mentioned.