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 !

1 votes

2 answers



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}";
0 votes

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.

0 votes

Thanks for your reply : it works good when you modify for the first time the "amount" metadata on a child document. But when you modify a second time this "amount", how can I compute the new "total" on the parent document ? I need to know the old value of the "amount" to remove it from the "total" before adding the new "amount" value… Is it possible to know the old value inside the automation chain ?

I can think of mainly three ways to do this, but none I know exactly how to implement, because I myself is very green in Nuxeo development and am trying to figure out how to do simple things.

  1. 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.

  2. 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.

  3. 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?