Expand my Community achievements bar.

Enhance your AEM Assets & Boost Your Development: [AEM Gems | June 19, 2024] Improving the Developer Experience with New APIs and Events
SOLVED

Include Parent Path in Index Definition

Avatar

Level 3

I have more than 1000 pages to query and the query will traverse nodes inside each page node to get component nodes. Let's assume all these pages are under the same parent node: /content/costco/, and this is what queries look like:

 

SELECT page.[jcr:path] FROM [nt:base] AS s WHERE ISDESCENDANTNODE([/content/costco/homepage1/jcr:content])

SELECT page.[jcr:path] FROM [nt:base] AS s WHERE ISDESCENDANTNODE([/content/costco/homepage2/jcr:content])

SELECT page.[jcr:path] FROM [nt:base] AS s WHERE ISDESCENDANTNODE([/content/costco/homepage3/jcr:content])

 

However, if I add index definition, it will need to include page paths one by one like below. 

 

<homepageDescendants
    jcr:primaryType="oak:QueryIndexDefinition"
    type="path"
    reindex="true">
    <indexRules jcr:primaryType="nt:unstructured">
        <nt:base jcr:primaryType="nt:unstructured">
            <properties jcr:primaryType="nt:unstructured">
                <path jcr:primaryType="nt:unstructured"
                       name="jcr:path"
                       unique="false"/>
            </properties>
        </nt:base>
    </indexRules>
    <includedPaths jcr:primaryType="nt:unstructured">
        <content jcr:primaryType="nt:unstructure name="/content/costco/homepage1/jcr:content"/>

        <content jcr:primaryType="nt:unstructure name="/content/costco/homepage2/jcr:content"/>

        <content jcr:primaryType="nt:unstructure name="/content/costco/homepage3/jcr:content"/>
    </includedPaths>
</homepageDescendants>

 

 

So if I have thousands of pages, I will need to create thousands of index definition. I was wondering if there's any way to add 1 index definition on its parent path such as /content/costco/:

 

    <includedPaths jcr:primaryType="nt:unstructured">
        <content jcr:primaryType="nt:unstructure name="/content/costco/jcr:content"/>
    </includedPaths>

1 Accepted Solution

Avatar

Correct answer by
Level 7

Hi @aemUser2345 ,

you can use the INCLUDE mechanism to index a large number of paths without explicitly listing each one. This allows you to specify a pattern for indexing rather than enumerating each path individually.

<homepageDescendants
    jcr:primaryType="oak:QueryIndexDefinition"
    type="path"
    reindex="true">
    <indexRules jcr:primaryType="nt:unstructured">
        <nt:base jcr:primaryType="nt:unstructured">
            <properties jcr:primaryType="nt:unstructured">
                <path jcr:primaryType="nt:unstructured" name="jcr:path" 
                 unique="false"/>
            </properties>
        </nt:base>
    </indexRules>
    <includedPaths jcr:primaryType="nt:unstructured">
        <content jcr:primaryType="nt:unstructured" 
         includePatterns="/content/costco/.*"/>
    </includedPaths>
</homepageDescendants>

the includePatterns property is used with a regular expression (/content/costco/.*) to match all paths under /content/costco/. This way, you don't have to list each path individually, and the index will cover all descendants of /content/costco/.

Thanks

View solution in original post

4 Replies

Avatar

Community Advisor

@aemUser2345  Is there any specific property value that you are trying to apply as a constraint in your query ? 

If so, you can create a property index to look for content nodes that satisfy a given constraint.

Avatar

Community Advisor

Hi @aemUser2345 

Yes, you can create a single index definition for the parent path /content/costco/ instead of creating individual index definitions for each page. This can be achieved by using the DESCENDANT operator in the query.

Here's an example of how you can modify the query to use the DESCENDANT operator:

SELECT page.[jcr:path] FROM [nt:base] AS s WHERE s.[jcr:path] LIKE '/content/costco/%/jcr:content' AND ISDESCENDANTNODE([/content/costco])

This query will return all pages under the /content/costco/ parent path that have a jcr:content child node. The LIKE operator is used to match the path pattern, and the ISDESCENDANTNODE function is used to ensure that only descendant nodes of the /content/costco/ parent path are returned.

By using this query, you can avoid the need to create individual index definitions for each page and instead rely on a single index definition for the parent path.



Avatar

Correct answer by
Level 7

Hi @aemUser2345 ,

you can use the INCLUDE mechanism to index a large number of paths without explicitly listing each one. This allows you to specify a pattern for indexing rather than enumerating each path individually.

<homepageDescendants
    jcr:primaryType="oak:QueryIndexDefinition"
    type="path"
    reindex="true">
    <indexRules jcr:primaryType="nt:unstructured">
        <nt:base jcr:primaryType="nt:unstructured">
            <properties jcr:primaryType="nt:unstructured">
                <path jcr:primaryType="nt:unstructured" name="jcr:path" 
                 unique="false"/>
            </properties>
        </nt:base>
    </indexRules>
    <includedPaths jcr:primaryType="nt:unstructured">
        <content jcr:primaryType="nt:unstructured" 
         includePatterns="/content/costco/.*"/>
    </includedPaths>
</homepageDescendants>

the includePatterns property is used with a regular expression (/content/costco/.*) to match all paths under /content/costco/. This way, you don't have to list each path individually, and the index will cover all descendants of /content/costco/.

Thanks

Avatar

Administrator

@aemUser2345 Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni