Reputation: 3597
When i use the below query on AEM QueryDebug
path=/content/dam/we-retail
type=dam:Asset
p.limit=-1
p.nodedepth=2
p.hits=full
p.guesstotal=true
And the formed URL/JSON QueryBuilder link.
I can see all the properties for each asset including jcr:content, metadata as below:
I need to return the same result to service/endpoint i'm building on AEM for a customer. When I translate the same above query into Query builder API
queryParamsMap.put("type", "dam:Asset");
queryParamsMap.put("p.limit", "-1");
queryParamsMap.put("p.nodedepth", "2");
queryParamsMap.put("p.hits", "full");
queryParamsMap.put("p.guessTotal", "true");
How can i retrieve all the values?
SearchResult result = query.getResult();
for (final Hit hit : result.getHits()) {
Resource resource = hit.getResource();
Asset asset = resource.adaptTo(Asset.class);
If i use asset.getMetadata()
, we can see only the properties under jcr:content\metadata
but not the other properties.
and
if i use ValueMap properties = resource.getValueMap();
we can retrieve all the asset properties (like jcr:path, jcr:primaryType etc) but not "metadata".
Is there any way to get all the values for an Asset node?
Upvotes: 0
Views: 7817
Reputation: 46
Another way to get all the properties of an AEM asset from the dam:Asset node itself to the metadata node (jcr:content/metadata) is using Apache Sling Models and adapting each resource returned by your query to this model.
For example:
@Model(adaptables=Resource.class)
public class MyAsset{
@Inject
@Named("jcr:created")
private String createdDate;
@Inject
@Named("jcr:createdBy")
private String createdBy;
@Inject
@Named("jcr:content/jcr:lastModified")
@Optional
private String lastModified;
@Inject
@Named("jcr:content/metadata/dc:title")
@Optional
private String title;
@Inject
@Named("jcr:content/metadata/dc:description")
@Optional
private String description;
@PostConstruct
protected void init() {
// You can code here any task needed to be executed after all the injections of the model are done
}
//getters and setters...
}
Note that you can specify any property of any descendant node of the resource using the annotation @Named.
I will suggest you use this approach if you need specific and few properties of the resource. If you need all properties I think the approach you found is better because you do not need to create a model to maintain all properties.
Using the model the final code will be:
for (Hit hit : result.getHits()) {
Resource resource = hit.getResource();
if(resource!=null){
MyAsset myAsset = resource.adaptTo(MyAsset.class);
Logger.info("The asset {} was modified on {}", myAsset.getTitle(), myAsset.getLastModified());
}
}
For more info about Sling Model you can refer to:
https://sling.apache.org/documentation/bundles/models.html
Upvotes: 1
Reputation: 3597
After some research, i found the below solution. Posting here for others reference.
As mentioned by @Imran-Saeed , there is no method that will return all the properties of an Asset (or a Node. Asset is also a node) in AEM. We have to do this in a combination.
jcr:created
, jcr:createdBy
, etc.jcr:content
level properties. These include cq:name
, cq:lastModified
, etcjcr:content\metadata
level properties. These include dc:title
, any custom metadata etc.ValueMap
that can hold all the properties of a particular Node/Asset.Below is a code snippet:
Resource resource;
ValueMap mainProperties;
ValueMap assetMetadataProperties;
Resource metadataResource;
ValueMap jcrProperties;
Resource jcrdataResource;
ValueMap allProperties;
for (Hit hit : result.getHits()) {
//LOGGER.info("\n********Hit path="+hit.getPath()+", title="+hit.getTitle());
resource = hit.getResource();
if(null!=resource){
mainProperties = resource.getValueMap();
// Add JCR Properties
jcrdataResource = resource.getChild("jcr:content");
jcrProperties = ResourceUtil.getValueMap(jcrdataResource);
// Add Metadata properties
metadataResource = resource.getChild("jcr:content/metadata");
assetMetadataProperties = ResourceUtil.getValueMap(metadataResource);
// Adding all togethe
allProperties = new ValueMapDecorator(new HashMap());
allProperties.putAll(hit.getProperties());
allProperties.putAll(mainProperties); // Includes jcr:created createdDate etc.
allProperties.put("jcr:path",hit.getPath()); //Add Path
allProperties.putAll(jcrProperties);
allProperties.putAll(assetMetadataProperties);
//LOGGER.debug("All Asset Properties="+new Gson().toJson(allProperties));
}
}
Note
jcr:path
is not returned by any of the above. So i had to explicitly add it using hit.getPath
hit.getTitle()
. Ofcourse this is also returned as part of cq:name
.Node
and retrieve the properties. com.day.cq.search.result.Hit
has a method getNode()
that returns a java.jcr.Node
interface and you can use that get to fetch the properties.Upvotes: 1