How to compute a metadata on a document according to a metadata of its children with automation ?
I have a metadata called “total” on a document. This document can have a variable number of children documents, all having a metadata called “amount”.
How can I parameter an automation chain to calculate the “total” from the parent document which must be equal to the sum of the “amount” of its children documents ?
Thanks for your help !
not the solution, but it can helps :
I did a groovy script for Nuxeo Shell, similar to your needs Hope it can inspire you
import org.nuxeo.ecm.core.api.IdRef;
import org.nuxeo.ecm.core.api.PathRef;
def ref = Context["ref"];
def docRoot = null;
if (ref == null || ref == "") { return "Context execution variable not set : ref"; }
try {
if (ref.startsWith("/")) {
docRoot = Session.getDocument(new PathRef(ref));
} else {
docRoot = Session.getDocument(new IdRef(ref));
}
} catch (Exception e) {
return "Exception: ${e.getMessage()}.";
}
def docRootAndChildren = [];
docRootAndChildren = Session.query("SELECT * FROM Folder WHERE ecm:path STARTSWITH '${docRoot.getPath()}'");
def total = 0;
for (doc in docRootAndChildren) {
total += Integer.parseInt(doc.getProperty("dublincore", "source"));
}
return "total = ${total}";
It seems to me the best bet is to implement somekind of event handler, listening change event on child document. Then child document get its parent to recalculate the total.
In "after modification" event listener, simply recalculate the total for the parent, regardless of the "old value". To do this, you either (a) iterate all the children of the parent, or (b) use Nuxeo's query mechanism to calculate the total (I'm not sure if Nuxeo's query mechanism allows this), or (c) try to obtain a database or Hibernate session and directly calculate with SQL / Hibernate query. This, in my opinion, is safer than method below but could be expensive, may require many database round trips depending on the number of children.
In a "before modification" event listener, deduct the "old value" from parent, then in an "after modification" event listener, add the "new value". However I am not sure how secure this method can be. If all event listeners are executed in one transaction then it should be safe, because either all operations success of nothing is changed. If the event listeners are not executed in one single transaction then this could be risky.
If the consistency of the "total" value is not demanded to be realtime, maybe you can simply write a cron job to directly update database table and run it periodically. This is most simple, a little bit ugly solution.
Any "Nuxeo Insider" has more comments?
Bing