問題
Web コンテンツの Elasticsearch に格納されている DDM フィールドを取得するために検索クエリを実行しようとしていますが、返されません。
同じコードが DXP 7.0、7.1、および 7.2 で機能し、DDM フィールドを次の 名前パターンを持つフィールド属性として返します:
ddm__keyword__99999__myfield__en_US
ddm__text__99999__myfield__en_US
DXP 7.3 および 7.4 で DDM フィールドを取得するようにコードを変更するにはどうすればよいですか?
Environment
- DXP 7.3
- DXP 7.4
解決策
LPS-103224 バグ修正の変更後、DDM フィールドは、「ddmFieldArray」という名前の ネストされたフィールド としてインデックス付けされるようになりました。この変更の詳細については、 DXP 7.3 重大な変更を参照してください。
デフォルトでは、Elasticsearch はこれらのネストされたフィールドをクエリ結果で返しません。
Elasticsearch の内部「_source」フィールドに格納されているドキュメント ソース フィールドから取得する必要があります ( https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-fields を参照)。 html ) に source: true
フラグを含めて、Elasticsearch がそのフィールドで結果を返すようにします。
このフラグは、SearchRequestBuilder の fetchSource(true) メソッドを呼び出す searchContent に追加されます。
- 例:
searchRequestBuilderFactory.builder(
searchContext
).fetchSource(
true
).build();
- 検索を実行した後、SearchResponse オブジェクトから Document オブジェクトを取得する必要があります。 この SearchResponse は、次のコードを使用して searchContext で利用できます。
/* 検索を実行します */
IndexSearcherHelperUtil.search(searchContext, query);
/* 検索レスポンスから結果を取得 */
SearchResponsesearchResponse = searchContext.getAttribute("search.response");
リスト<SearchHit> resultHits = searchResponse.getSearchHits().getSearchHits();
/* 反復 */
for (SearchHit searchHit : resultHits) {
ドキュメントdoc= searchHit.getDocument();
...あなたのコード...
}
次の Liferay クラスで、ソースの取得と SearchResponse の取得に関する例がいくつかあります。
- com.liferay.document.library.search.test.DLSearchFixture、fetchSource(true) が設定され、SearchResponse オブジェクトが searchContext から取得されるメソッド searchOnlyOneSearchHit を参照してください
- com.liferay.account.internal.retriever.AccountOrganizationRetrieverImpl SearchRequest と SearchResponse を使用していくつかの検索が行われます。
- com.liferay.asset.internal.util.AssetHelperImpl searchRequestBuilderFactory が使用されます。
コントロール パネル => サーバー管理 => スクリプトから実行できる groovy スクリプトの例を次に示します。
- 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 */
Registryregistry= RegistryUtil.getRegistry();
SearchRequestBuilderFactorysearchRequestBuilderFactory= registry.getService(registry.getServiceReference(SearchRequestBuilderFactory.class.getName()));
/* Create SearchContext */
SearchContextsearchContext=newSearchContext();
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) */
MatchQueryapprovedQuery=newMatchQuery(Field.STATUS, String.valueOf(0));
MatchQueryjournalArticleQuery=newMatchQuery("entryClassName", com.liferay.journal.model.JournalArticle.class.getName());
BooleanQueryquery=newBooleanQueryImpl();
query.add(approvedQuery, BooleanClauseOccur.MUST.getName());
query.add(journalArticleQuery, BooleanClauseOccur.MUST.getName());
/* Execute search */
IndexSearcherHelperUtil.search(searchContext, query);
/* Get results from search response */
SearchResponsesearchResponse= searchContext.getAttribute("search.response");
List<SearchHit> resultHits = searchResponse.getSearchHits().getSearchHits();
/* Iterate */
for (SearchHit searchHit : resultHits) {
Documentdoc= searchHit.getDocument();
out.println("entryClassPK: " + doc.getValue("entryClassPK"));
out.println("ddmFieldArray: " + doc.getValues("ddmFieldArray"));
out.println("");
}
- 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 */
BundleContextbundleContext= SystemBundleUtil.getBundleContext();
SearchRequestBuilderFactorysearchRequestBuilderFactory= bundleContext.getService(bundleContext.getServiceReferences(SearchRequestBuilderFactory.class.getName(), null)[0]);
/* Create SearchContext */
SearchContextsearchContext=newSearchContext();
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) */
MatchQueryapprovedQuery=newMatchQuery(Field.STATUS, String.valueOf(0));
MatchQueryjournalArticleQuery=newMatchQuery("entryClassName", com.liferay.journal.model.JournalArticle.class.getName());
BooleanQueryquery=newBooleanQueryImpl();
query.add(approvedQuery, BooleanClauseOccur.MUST.getName());
query.add(journalArticleQuery, BooleanClauseOccur.MUST.getName());
/* Execute search */
IndexSearcherHelperUtil.search(searchContext, query);
/* Get results from search response */
SearchResponsesearchResponse= searchContext.getAttribute("search.response");
List<SearchHit> resultHits = searchResponse.getSearchHits().getSearchHits();
/* Iterate */
for (SearchHit searchHit : resultHits) {
Documentdoc= searchHit.getDocument();
out.println("entryClassPK: " + doc.getValue("entryClassPK"));
out.println("ddmFieldArray: " + doc.getValues("ddmFieldArray"));
out.println("");
}
コードでは、RegistryUtil または BundleContext の使用を「@Reference」アノテーションに置き換える必要があります。
追加情報