Can you submit multiple calls to NodeService.getProperties at once?

cancel
Showing results for 
Search instead for 
Did you mean: 
mnybon
Member II

Can you submit multiple calls to NodeService.getProperties at once?

TLSmiley Very HappyR: I am using Alfresco 5.1 and I was wondering if there is a way to optimize queries to the nodeservice in case of a large query involving a bunch of nodes and properties.


For example, say that I have this model:


<model name="My model" xmlns="http://www.alfresco.org/model/dictionary/1.0">

   ...


    <type name="ParentNode">
        <title>The parent that i want to retrieve</title>
        <parent>cm:cmobject</parent>
        <associations>
            <child-association name="ParentChildA">
                <source>
                    <mandatory>true</mandatory>
                    <many>false</many>
                </source>
                <target>
                    <class>ChildA</class>
                    <mandatory>false</mandatory>
                    <many>true</many>
                </target>
                <duplicate>false</duplicate>
            </child-association>
        </associations>      
    </type>


    <type name="ChildA">
        <title>First layer of children</title>
        <parent>cm:cmobject</parent>

        <properties>
            <property name="ChildAName">
                <type>dSmiley Frustratedtring</type>
                <mandatory>true</mandatory>
            </property>
        </properties>
        <associations>
            <child-association name="ChildAChildB">
                <source>
                    <mandatory>true</mandatory>
                    <many>true</many>
                </source>
                <target>
                    <class>ChildB</class>
                    <mandatory>false</mandatory>
                    <many>true</many>
                </target>
                <duplicate>false</duplicate>
            </child-association>
        </associations>      
    </type>


    <type name="ChildB">
        <title>Second layer of children</title>
        <parent>cm:cmobject</parent>
        <properties>
            <property name="ChildBName">
                <type>dSmiley Frustratedtring</type>
                <mandatory>true</mandatory>
            </property>

            <property name="ChildBOtherProperty">
                <type>dSmiley Frustratedtring</type>
            </property>
        </properties>
    </type>


</model>

I need to create a list of all ChildA nodes that are children of the ChildAssociation "ParentChildA" for a certain node of type ParentNode. So for one specific "ParentNode", I need to get all its ChildA children and all ChildB children of those ChildA nodes.


The way i would normally go about this would be to get the NodeRef of the ParentNode and use the NodeService getChildAssocs(NodeRef nodeRef, QNamePattern typeQNamePattern, QNamePattern qnamePattern) to get the ChildA nodes, and then get the ChildB nodes again using the same method. Then i would get the properties of those nodes using the getProperties(NodeRef nodeRef).

This is really slow however. With about 80 nodes the request takes 3-4 seconds to complete. My guess is that each call to getProperties is its own database query.

So I am wondering, if there is a way to submit tne entire request to the database at once, instead of firing a request for each node? The database seems reasonably well indexed, so the waiting time should really not be this long.

Thank you for any help you can provide Smiley Happy

3 Replies
Renesto
Member II

Re: Can you submit multiple calls to NodeService.getProperties at once?

Hi mnybon,

 

im facing the same Problem right now, did you find a Solution to this ?

abhinavmishra14
Advanced

Re: Can you submit multiple calls to NodeService.getProperties at once?

Properties are associated with each node in alfresco repository and to get the properties associated with each node you have to make the nodeService.getProperties(nodeRef) call. 

When you start with the parent node where you have created associations and want to get the list of associated nodes, you use nodeService.getChildAssocs(........) call, as you are doing. After getting the list of ChildAssocRef, to get the noderef of the child, you call childAssocNode.getChildRef() and using this nodeRef you get the properties pertaining to each child node. 

The steps you are following seems correct, and to my knowledge there is no other way to get all child nodes and pass all nodeRefs at once and get the properties associated with each node. It has to be node by node call. There is no service/api which can provide this kind of results unless you want to get till the db level calls and do some customizations. 

Maybe someone else will have a more precise answer and somewhere to look.

 

~Abhinav
(ACSCE, AWS SAA, Azure Admin)
afaust
Master

Re: Can you submit multiple calls to NodeService.getProperties at once?

That is correct - there is no operation to get properties for multiple nodes in one call. And there is no need for such an operation, as that would not make sense - as you described, properties are always associated to specifically one node and that association is necessary for metadata to make sense. The only reason I can think of why you would want to perform the properties retrieval in one operation / call might be performance, e.g. the believe that by doing it in one operation, it may be more efficient. This is generally true - though the extent depends on the current state of Alfresco caches and what API you used to retrieve the list of nodes.

E.g. if you retrieved nodes via a FTS search against SOLR, the properties for each node will already be pre-loaded into caches. So when you call getProperties on each result, Alfresco will actually not have to perform additional database calls to get the properties and the calls will be fast. The only performance overhead of doing multiple calls in this case may be permission checks, but these are perfectly valid / necessary, as each node can have different permissions applied to it.

If you retrieve lists of (child) nodes via NodeService APIs, the properties may actually not be pre-cached (unless the same node was already accessed in previous transactions) and each call to getProperties may perform additional DB calls. The NodeService does not provide an API to remedy this, but the NodeBulkLoader API (an internal interface, not considered part of the Alfresco Public Java API) allows to pre-cache nodes in one bulk operation for improved performance, if really necessary.