06-30-2020 01:18 PM
Hello community
As the title says, i was searching in the community content about any available endpoints to apply aspects in bulk on several nodes in one or more sites. I have 4-5 aspects which i have added to my content model which i want to apply to old nodes
Is there anything available already or do i need to create a custom WebScript or something?
Appreciate any hint/guidance
06-30-2020 08:39 PM
As far as i know, there are no ootb rest api which can be used for your use case. However, there is a way to add/remove aspects to one node.
You can see details here:
https://javaworld-abhinav.blogspot.com/2017/06/addremove-aspects-on-node-in-alfresco.html
For applying aspects to multiple nodes to a specific site or on all the available sites, you can do following:
1- Create a java backed or repo (js) webscript which will search for the nodes in site for missing aspect.
2- You can target one site at a time or you can list all sites and iterate on iterate
3- Search query would be something like:
PATH:"/app:company_home/st:sites/cm:test-site/cm:documentLibrary//*" AND (TYPE:"cm:content" AND NOT ASPECT:"xyz:aspectName" AND NOT ASPECT:"cm:lockable") [Here, cm:test-site is the site short name.]
You can limit the search to a specific folder and custom content types as well.
4- Iterate on resulted nodes and apply the aspect using NodeService (when using java backed webscript) or call addAspect on node (node.addAspect("xyz:aspectName")).
Here is a sample repo (js) webscript, you can take reference from it and tweak it as per your need, It allows applying aspect to all the sites based on search query:
apply-aspect.get.js main(); function main(){ var aspectName = args["aspectName"]; var contentType = args["contentType"]; var skipCount = (args["skipCount"]==null || args["skipCount"]==undefined)?0:args["skipCount"]; //defaults to 0, if argument is not passed. var maxCount = (args["maxCount"]==null || args["maxCount"]==undefined)?100000:args["maxCount"]; //defaults to 100000, if argument is not passed. var successfullNodes = []; var erroredNodes = []; var query = 'PATH:"/app:company_home/st:sites//*" AND TYPE:"'+contentType+'" AND NOT ASPECT:"'+aspectName+'" AND NOT ASPECT:"cm:lockable"'; var page = { skipCount : parseInt(skipCount), maxItems : parseInt(maxCount) }; var searchQuery = { query : query, language : "lucene", page : page }; logger.log("Query for search: "+query) var nodes = search.query(searchQuery); logger.log("Resulted Nodes: "+nodes.length) for each(node in nodes) { try { if(!node.hasAspect(aspectName)){ node.addAspect(aspectName); successfullNodes[node.nodeRef] = "Aspect '"+aspectName+"' applied successfully to: " +node.name; } } catch(excp) { logger.log("Failed to apply aspect due to: "+excp.message); erroredNodes[node.nodeRef] = "Aspect '"+aspectName+"' could not be applied to: " +node.name+", due to: "+excp.message; } } //Put the result in model so that we can display it in a template
model.successfullNodes = successfullNodes; model.erroredNodes = erroredNodes; }
You can also refer this documentation on creating/deploying the webscripts:
https://docs.alfresco.com/5.2/references/dev-extension-points-webscripts.html
06-30-2020 08:39 PM
As far as i know, there are no ootb rest api which can be used for your use case. However, there is a way to add/remove aspects to one node.
You can see details here:
https://javaworld-abhinav.blogspot.com/2017/06/addremove-aspects-on-node-in-alfresco.html
For applying aspects to multiple nodes to a specific site or on all the available sites, you can do following:
1- Create a java backed or repo (js) webscript which will search for the nodes in site for missing aspect.
2- You can target one site at a time or you can list all sites and iterate on iterate
3- Search query would be something like:
PATH:"/app:company_home/st:sites/cm:test-site/cm:documentLibrary//*" AND (TYPE:"cm:content" AND NOT ASPECT:"xyz:aspectName" AND NOT ASPECT:"cm:lockable") [Here, cm:test-site is the site short name.]
You can limit the search to a specific folder and custom content types as well.
4- Iterate on resulted nodes and apply the aspect using NodeService (when using java backed webscript) or call addAspect on node (node.addAspect("xyz:aspectName")).
Here is a sample repo (js) webscript, you can take reference from it and tweak it as per your need, It allows applying aspect to all the sites based on search query:
apply-aspect.get.js main(); function main(){ var aspectName = args["aspectName"]; var contentType = args["contentType"]; var skipCount = (args["skipCount"]==null || args["skipCount"]==undefined)?0:args["skipCount"]; //defaults to 0, if argument is not passed. var maxCount = (args["maxCount"]==null || args["maxCount"]==undefined)?100000:args["maxCount"]; //defaults to 100000, if argument is not passed. var successfullNodes = []; var erroredNodes = []; var query = 'PATH:"/app:company_home/st:sites//*" AND TYPE:"'+contentType+'" AND NOT ASPECT:"'+aspectName+'" AND NOT ASPECT:"cm:lockable"'; var page = { skipCount : parseInt(skipCount), maxItems : parseInt(maxCount) }; var searchQuery = { query : query, language : "lucene", page : page }; logger.log("Query for search: "+query) var nodes = search.query(searchQuery); logger.log("Resulted Nodes: "+nodes.length) for each(node in nodes) { try { if(!node.hasAspect(aspectName)){ node.addAspect(aspectName); successfullNodes[node.nodeRef] = "Aspect '"+aspectName+"' applied successfully to: " +node.name; } } catch(excp) { logger.log("Failed to apply aspect due to: "+excp.message); erroredNodes[node.nodeRef] = "Aspect '"+aspectName+"' could not be applied to: " +node.name+", due to: "+excp.message; } } //Put the result in model so that we can display it in a template
model.successfullNodes = successfullNodes; model.erroredNodes = erroredNodes; }
You can also refer this documentation on creating/deploying the webscripts:
https://docs.alfresco.com/5.2/references/dev-extension-points-webscripts.html
07-07-2020 12:07 PM
Thanks a lot, it worked.
Explore our Alfresco products with the links below. Use labels to filter content by product module.