dgi*_*aig 2 java portlet liferay elasticsearch liferay-7
我正在尝试使用 SearchContext、IndexSearcherHelperUtil 和所有其他东西为 Liferay 7.3.5 GA6 开发一个自定义 Web 内容搜索 portlet。
\n我有一些具有不同字段的 DDMStructure,从我在 elasticsearch 索引上看到的情况来看,这些字段在嵌套文档中建立索引,如下所示:
\n"ddmFieldArray": [\n{\n"ddmFieldName": "ddm__text__37702__nome_it_IT",\n"ddmValueFieldName": "ddmFieldValueText_it_IT",\n"ddmFieldValueText_it_IT": "Nome esempio",\n"ddmFieldValueText_it_IT_String_sortable": "nome esempio"\n}\n,\n{\n"ddmFieldName": "ddm__text__37702__descrizione_breve_it_IT",\n"ddmValueFieldName": "ddmFieldValueText_it_IT",\n"ddmFieldValueText_it_IT": "Esempio di descrizione breve da indicizzare",\n"ddmFieldValueText_it_IT_String_sortable": "esempio di descrizione breve da indicizzare"\n}\n]\n
Run Code Online (Sandbox Code Playgroud)\n这与我以前知道的旧方式不同,其中自定义字段的索引如下ddm__[keyword/text]__[structure_id]__[field_name]
现在,我明白\xc2\xa0这种不同的索引方式是由于为了避免弹性问题而进行的改进(已超出总字段的限制)但是......执行搜索后, com.liferay.portal中没有ddmFieldArray .kernel.search.Document .getFields,因此我无法从弹性搜索索引中获取 ddmstruct 字段值。
\n这是代码:
\nlong journalArticleClassId = ClassNameLocalServiceUtil.getClassNameId(JournalArticle.class.getName());\n\nSearchContext searchContext = new SearchContext();\nsearchContext.setClassTypeIds(new long[] {journalArticleClassId});\nsearchContext.setCompanyId(companyId);\nsearchContext.setStart(QueryUtil.ALL_POS);\nsearchContext.setEnd(QueryUtil.ALL_POS);\n \nBooleanQuery query = new BooleanQueryImpl();\n \n \nMatchQuery approvedQuery = new MatchQuery(Field.STATUS, String.valueOf(WorkflowConstants.STATUS_APPROVED));\n\nquery.add(approvedQuery, BooleanClauseOccur.MUST.getName());\n\n\nHits resultHits = IndexSearcherHelperUtil.search(searchContext, query);\n\nfor (Document doc: resultHits.getDocs()) { \n doc.getFields().forEach((k, v) -> _log.debug(k)); //No ddm structure field\n}\n
Run Code Online (Sandbox Code Playgroud)\n这仍然是一种改进还是只是一种意外行为?
\n有什么办法可以解决或扩展这个问题吗?
\n谢谢
\n“ddmFieldArray”字段是一个嵌套字段,默认情况下不返回。您必须从存储在 Elasticsearch 内部“_source”字段中的文档源字段中获取它(请参阅https://www.elastic.co/guide/en/elasticsearch/reference/7.9/search-fields.html)
为了在 Liferay 中做到这一点,您必须使用旧的门户内核搜索类中不可用的一些搜索方法,您必须使用门户搜索 api模块中可用的新搜索类,该模块是位于模块/应用程序/门户搜索
这些是您必须应用于代码的更改:
searchRequestBuilderFactory.builder(
searchContext
).fetchSource(
true
).build();
Run Code Online (Sandbox Code Playgroud)
/* Execute search */
IndexSearcherHelperUtil.search(searchContext, query);
/* Get results from search response */
SearchResponse searchResponse = searchContext.getAttribute("search.response");
List<SearchHit> resultHits = searchResponse.getSearchHits().getSearchHits();
/* Iterate */
for (SearchHit searchHit : resultHits) {
Document doc = searchHit.getDocument();
...your stuff...
}
Run Code Online (Sandbox Code Playgroud)
您在以下 Liferay 类中有一些关于获取源代码和获取 SearchResponse 的示例:
我还实现了一个 groovy 脚本示例,您可以从以下位置执行它:控制面板 => 服务器管理 => 脚本
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<SearchHit> 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("");
}
Run Code Online (Sandbox Code Playgroud)
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<SearchHit> 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("");
}
Run Code Online (Sandbox Code Playgroud)
在您的代码中,您应该使用“@Reference”注释替换RegistryUtil 或BundleContext 用法。
如果您对我的示例有任何疑问,请告诉我。
归档时间: |
|
查看次数: |
2240 次 |
最近记录: |