Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
SOLVED

Lucene index, CustomScoreQuery. AEM6.3

Avatar

Level 2

Hi,

I have a query that finds all pages and all pdf files in specific paths using QueryBuilder and lucene index. The PDF part is not currently relevant for the question.

I would like to have number property on each page node, lets call it "luceneScoreModifier" that will alter the calculate the jcr:score. The property value should be multiplied into the calculate jcr:score to boost the page up in result.

I have found something calles CustomScoreQuery with CustomScoreProvide that could help my needs

Examples with ScorerProvider - org.apache.jackrabbit.oak.plugins.index.lucene.score.ScorerProvider

But unfortunetely i do not know how to use it with QueryBuilder.

Do You know how my goal can be achieved or point me to the right direction ??

For the records here is my predicateGroup and xpath for the query.

        Map<String, String> map = new HashMap<String, String>();

        map.put("fulltext" , fulltextSearchTerm);

        map.put("orderby" , "@jcr:score");

        map.put("orderby.sort" , "desc");

        map.put("group.p.or", "true");

        map.put("group.1_group.type", "cq:Page");

        map.put("group.1_group.path", rootSitePath);

        map.put("group.1_group.property" , "jcr:content/index");

        map.put("group.1_group.property.operation" , JcrPropertyPredicateEvaluator.OP_EXISTS);

        map.put("group.1_group.property.value" , "false");

        map.put("group.2_group.type", "dam:Asset");

        map.put("group.2_group.path", rootAssetPath);

        map.put("group.2_group.property" , "jcr:content/metadata/dc:format");

        map.put("group.2_group.property.value" , "application/pdf");

        PredicateGroup.create(map);

Xpath

/jcr:root/content/siteName//element(*, cq:Page)[(not(jcr:content/@index)) and (jcr:contains(., 'test'))] | /jcr:root/content/dam/siteName//element(*, dam:Asset)[(jcr:content/metadata/@dc:format = 'application/pdf') and (jcr:contains(., 'test'))]) order by @jcr:score descending

1 Accepted Solution

Avatar

Correct answer by
Level 4

Hi,

Please try creating a custom lucene index, details on oak indexing at Oak Queries and Indexing .

You can find a sample index file at Keep Calm and Code It.: AEM Search Suggestions just in case needed.

next, try adding boost to certain node types based on certain conditions as specified in IndexingConfiguration - Jackrabbit Wiki

This is something you would want:

<?xml version="1.0"?>

<!DOCTYPE configuration SYSTEM "http://jackrabbit.apache.org/dtd/indexing-configuration-1.0.dtd">

<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">

  <index-rule nodeType="nt:unstructured"

  boost="2.0"

  condition="@priority = 'high'">

  <property>Text</property>

  </index-rule>

  <index-rule nodeType="nt:unstructured">

  <property>Text</property>

  </index-rule>

</configuration>

When the index would be configured, all the queries (SQL2 and XPath) would return results accordingly.

Let me know if this helped.

Thanks

Rima Mittal

View solution in original post

5 Replies

Avatar

Level 10

When you execute that query - what are the results?

Avatar

Level 2

The result are correct . I am able to recieve both pages and pdf files.

The problem is that I would like to be able to influence the page importance, by a page property.

Lets say that we have three page results

Page A - jcr:score - 10

Page B - jcr:score - 6

Page C - jcr:score - 4

I would like to have a property on all pages that can boost a page jcr:score. Assuming Page C contains a property called 'luceneScoreModifier' with value 3, then the overall jcr:score for Page C would be 12 (4*3) and the correct order would be :

Page C - jcr:score - 12
Page A - jcr:score - 10
Page B - jcr:score - 6

Do You know how can i achieve this kind of solution ?

Avatar

Level 4

Hi,

I think what might help is a boost. Please refer IndexingConfiguration - Jackrabbit Wiki to see how to configure boost on nodes.

Alternatively, instead of ordering by jcr:score in the queries, order by a custom property and handle the scoring all manual.

But if you want to go by jcr:score, then boost might be helpful.

Thanks

Rima Mittal

Avatar

Level 2

Hi Rima,

The boosting is great, but i can see that i can boost only one property at a time not whole page, so that not exactly suits my needs.

In SQL i can write a query like this :

SELECT jcr_score*boost_value as orderValue FROM someTable order by orderValue.

Do You know if i can write similar query using JCR_SQL2 ?

Maybe something like this :

select [jcr:path], [jcr:score] * [a/jcr:content/boostValue] as orderValue, *

  from [cq:Page] as a

where [jcr:content/index] is null

  and contains(*, 'test')

  and isdescendantnode(a, '/content/sitename')

order by orderValue

Avatar

Correct answer by
Level 4

Hi,

Please try creating a custom lucene index, details on oak indexing at Oak Queries and Indexing .

You can find a sample index file at Keep Calm and Code It.: AEM Search Suggestions just in case needed.

next, try adding boost to certain node types based on certain conditions as specified in IndexingConfiguration - Jackrabbit Wiki

This is something you would want:

<?xml version="1.0"?>

<!DOCTYPE configuration SYSTEM "http://jackrabbit.apache.org/dtd/indexing-configuration-1.0.dtd">

<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">

  <index-rule nodeType="nt:unstructured"

  boost="2.0"

  condition="@priority = 'high'">

  <property>Text</property>

  </index-rule>

  <index-rule nodeType="nt:unstructured">

  <property>Text</property>

  </index-rule>

</configuration>

When the index would be configured, all the queries (SQL2 and XPath) would return results accordingly.

Let me know if this helped.

Thanks

Rima Mittal