Legacy Knowledge Base
Published Jun. 30, 2025

Cannot get the DDM fields stored in ddmFieldArray Elasticsearch nested field when executing a search from Java code

Written By

Jorge Diaz

How To articles are not official guidelines or officially supporteddocumentation. They are community-contributed content and may not alwaysreflect the latest updates to Liferay DXP. We welcome your feedback toimprove How to articles!

While we make every effort to ensure this Knowledge Base is accurate, itmay not always reflect the most recent updates or official guidelines.We appreciate your understanding and encourage you to reach out with anyfeedback or concerns.

Legacy Article

You are viewing an article from our legacy "FastTrack"publication program, made available for informational purposes. Articlesin this program were published without a requirement for independentediting or verification and are provided "as is" withoutguarantee.

Before using any information from this article, independently verify itssuitability for your situation and project.

Issue

I am trying to execute a search query to get the DDM fields stored in Elasticsearch of web content but they are not being returned.

The same code was working in DXP 7.0, 7.1, and 7.2, returning the DDM fields as field attributes with this name pattern:

ddm__keyword__99999__myfield__en_US
ddm__text__99999__myfield__en_US

How can I adapt my code to get the DDM fields in DXP 7.3 and 7.4?

Environment

  • DXP 7.3
  • DXP 7.4

Resolution

After the LPS-103224 bug fix changes, the DDM fields are now indexed as a nested field named "ddmFieldArray", for more information about this change, see DXP 7.3 breaking changes.

By default, Elasticsearch doesn't return these nested fields in the query results.

You have to fetch it from the document source field that is stored in an internal "_source" field in Elasticsearch (see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-fields.html ) including the source: true flag so that  Elasticsearch returns the results with that fields. 

This flag is added to the searchContent invoking the fetchSource(true) method of SearchRequestBuilder.

  • Example:
    searchRequestBuilderFactory.builder( 
searchContext
).fetchSource(
true
).build();
  • After executing the search, you have to get the Document objects from the SearchResponse object. This SearchResponse is available in the searchContext using this code:
/* Execute search */ 
IndexSearcherHelperUtil.search(searchContext, query);

/* Get results from search response */
SearchResponse searchResponse = searchContext.getAttribute("search.response");
List resultHits = searchResponse.getSearchHits().getSearchHits();

/* Iterate */
for (SearchHit searchHit : resultHits) {
Document doc = searchHit.getDocument();

...your stuff...
}

You have some examples about fetching source and gettings SearchResponse in the following Liferay classes:

Here there is a groovy script example that you can execute from Control Panel => Server Administration => Script

  • Code for DXP 7.3
import com.liferay.registry.*; 
import com.liferay.portal.kernel.search.*;
import com.liferay.portal.kernel.search.generic.*;
import com.liferay.portal.search.legacy.searcher.SearchRequestBuilderFactory;
import com.liferay.portal.search.searcher.SearchResponse;
import com.liferay.portal.search.hits.SearchHit;
import com.liferay.portal.search.document.Document;

/* Get SearchRequestBuilderFactory reference using RegistryUtil, because we cannot use "@Reference" in a groovy script */ Registry registry = RegistryUtil.getRegistry();
SearchRequestBuilderFactory searchRequestBuilderFactory = registry.getService(registry.getServiceReference(SearchRequestBuilderFactory.class.getName()));

/* Create SearchContext */
SearchContext searchContext = new SearchContext();
searchContext.setCompanyId(com.liferay.portal.kernel.util.PortalUtil.getCompany(actionRequest).getCompanyId());
searchContext.setStart(-1);
searchContext.setEnd(-1);

/* Line to fetch stored source of documents */
searchRequestBuilderFactory.builder(
searchContext
).fetchSource(
true
).build();

/* Get journal articles that are approved (status = 0) */
MatchQuery approvedQuery = new MatchQuery(Field.STATUS, String.valueOf(0));
MatchQuery journalArticleQuery = new MatchQuery("entryClassName", com.liferay.journal.model.JournalArticle.class.getName());

BooleanQuery query = new BooleanQueryImpl();
query.add(approvedQuery, BooleanClauseOccur.MUST.getName());
query.add(journalArticleQuery, BooleanClauseOccur.MUST.getName());

/* Execute search */
IndexSearcherHelperUtil.search(searchContext, query);

/* Get results from search response */
SearchResponse searchResponse = searchContext.getAttribute("search.response");
List resultHits = searchResponse.getSearchHits().getSearchHits();

/* Iterate */
for (SearchHit searchHit : resultHits) {
Document doc = searchHit.getDocument();
out.println("entryClassPK: " + doc.getValue("entryClassPK"));
out.println("ddmFieldArray: " + doc.getValues("ddmFieldArray"));
out.println("");
}
  • Code for DXP 7.4
import com.liferay.portal.kernel.search.*; 
import com.liferay.portal.kernel.search.generic.*;
import com.liferay.portal.search.legacy.searcher.SearchRequestBuilderFactory;
import com.liferay.portal.search.searcher.SearchResponse;
import com.liferay.portal.search.hits.SearchHit;
import com.liferay.portal.search.document.Document;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;

import com.liferay.portal.kernel.module.util.SystemBundleUtil;

/* Get SearchRequestBuilderFactory reference using the BundleContext, because we cannot use "@Reference" in a groovy script */
BundleContext bundleContext = SystemBundleUtil.getBundleContext();
SearchRequestBuilderFactory searchRequestBuilderFactory = bundleContext.getService(bundleContext.getServiceReferences(SearchRequestBuilderFactory.class.getName(), null)[0]);

/* Create SearchContext */
SearchContext searchContext = new SearchContext();
searchContext.setCompanyId(com.liferay.portal.kernel.util.PortalUtil.getCompany(actionRequest).getCompanyId());
searchContext.setStart(-1);
searchContext.setEnd(-1);

/* Line to fetch stored source of documents */
searchRequestBuilderFactory.builder(
searchContext
).fetchSource(
true
).build();

/* Get journal articles that are approved (status = 0) */
MatchQuery approvedQuery = new MatchQuery(Field.STATUS, String.valueOf(0));
MatchQuery journalArticleQuery = new MatchQuery("entryClassName", com.liferay.journal.model.JournalArticle.class.getName());

BooleanQuery query = new BooleanQueryImpl();
query.add(approvedQuery, BooleanClauseOccur.MUST.getName());
query.add(journalArticleQuery, BooleanClauseOccur.MUST.getName());

/* Execute search */
IndexSearcherHelperUtil.search(searchContext, query);

/* Get results from search response */
SearchResponse searchResponse = searchContext.getAttribute("search.response");
List resultHits = searchResponse.getSearchHits().getSearchHits();

/* Iterate */
for (SearchHit searchHit : resultHits) {
Document doc = searchHit.getDocument();
out.println("entryClassPK: " + doc.getValue("entryClassPK"));
out.println("ddmFieldArray: " + doc.getValues("ddmFieldArray"));
out.println("");
}

In your code, you should replace the RegistryUtil or BundleContext usage with the "@Reference" annotation.

"Entity content is too long" error executing the script

If you get an "entity content is too long" error executing the script:

2023-03-07 11:53:04.136 ERROR [http-nio-8080-exec-72][ElasticsearchIndexSearcher:164] null
java.lang.RuntimeException: java.io.IOException: entity content is too long [155989434] for the configured buffer limit [104857600]
at com.liferay.portal.search.elasticsearch7.internal.search.engine.adapter.search.SearchSearchRequestExecutorImpl.getSearchResponse(SearchSearchRequestExecutorImpl.java:99) ~[?:?]
{...}
Caused by: org.apache.http.ContentTooLongException: entity content is too long [155989434] for the configured buffer limit [104857600]

This is caused because the example query returns too many articles for a single request.

See article: Entity content is too long for the configured buffer limit

To avoid this error, change the example query to return fewer articles

 

Additional Information

 

 

 

Did this article resolve your issue ?

Legacy Knowledge Base