TLR: 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>dtring</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>dtring</type>
<mandatory>true</mandatory>
</property>
<property name="ChildBOtherProperty">
<type>dtring</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
Hi mnybon,
im facing the same Problem right now, did you find a Solution to this ?
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.
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.
Ask for and offer help to other Alfresco Content Services Users and members of the Alfresco team.
Related links:
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.