当前位置: 首页 > 知识库问答 >
问题:

Liferay 7.3.5GA6自定义索引搜索和ddmFieldArray

柏夕
2023-03-14

我正在尝试使用SearchContext、IndexSearcherHelperUtil和所有其他东西,为Liferay 7.3.5 GA6开发一个定制的web内容搜索portlet。

我有一些不同字段的DDM结构,从我在elasticsearch索引上看到的,这些字段在嵌套文档中被索引,如下所示:

"ddmFieldArray": [
{
"ddmFieldName": "ddm__text__37702__nome_it_IT",
"ddmValueFieldName": "ddmFieldValueText_it_IT",
"ddmFieldValueText_it_IT": "Nome esempio",
"ddmFieldValueText_it_IT_String_sortable": "nome esempio"
}
,
{
"ddmFieldName": "ddm__text__37702__descrizione_breve_it_IT",
"ddmValueFieldName": "ddmFieldValueText_it_IT",
"ddmFieldValueText_it_IT": "Esempio di descrizione breve da indicizzare",
"ddmFieldValueText_it_IT_String_sortable": "esempio di descrizione breve da indicizzare"
}
]

这与我以前知道的旧方法不同,在旧方法中,自定义字段被索引ddm__[keyword/text]__[structure_uid]__[field_name]

现在我明白了

以下是代码:

long journalArticleClassId = ClassNameLocalServiceUtil.getClassNameId(JournalArticle.class.getName());

SearchContext searchContext = new SearchContext();
searchContext.setClassTypeIds(new long[] {journalArticleClassId});
searchContext.setCompanyId(companyId);
searchContext.setStart(QueryUtil.ALL_POS);
searchContext.setEnd(QueryUtil.ALL_POS);
        
BooleanQuery query = new BooleanQueryImpl();
            
        
MatchQuery approvedQuery = new MatchQuery(Field.STATUS, String.valueOf(WorkflowConstants.STATUS_APPROVED));

query.add(approvedQuery, BooleanClauseOccur.MUST.getName());


Hits resultHits = IndexSearcherHelperUtil.search(searchContext, query);

for (Document doc: resultHits.getDocs()) {          
    doc.getFields().forEach((k, v) -> _log.debug(k)); //No ddm structure field
}

这仍然是一种进步,还是只是一种意外的行为?

有没有办法解决或扩展这个问题?

谢啦

共有1个答案

汪建白
2023-03-14

“ddmFieldArray”字段是一个嵌套字段,默认情况下不会返回该字段。您必须从Elasticsearch中存储在内部“_source”字段中的文档源字段中获取它(请参见https://www.elastic.co/guide/en/elasticsearch/reference/7.9/search-fields.html )

为了在Liferay中实现这一点,您必须使用旧门户内核搜索类中不可用的一些搜索方法,您必须使用位于modules/apps/portal search中的门户搜索api模块中可用的新搜索类

这些是必须应用于代码的更改:

  • 在执行搜索之前,必须将“fetchSource”标志添加到搜索中添加以下代码:
    searchRequestBuilderFactory.builder(
        searchContext
    ).fetchSource(
        true
    ).build();
  • 执行搜索后,您必须从SearchContent对象中获取文档对象。此搜索响应可在search chContext中使用以下代码:
    /* 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...
    }

在以下Liferay类中,您有一些关于获取源代码和获取搜索响应的示例:

  • com。利弗雷。文件图书馆搜索测验DLSearchFixture,请参阅方法searchOnlyOneSearchHit,其中设置了fetchSource(true),并从searchContext获取SearchResponse对象
  • com。利弗雷。账户内部的猎犬。AccountOrganizationRetrieverImpl,其中一些搜索是使用SearchRequest和SearchResponse完成的
  • com。利弗雷。资产内部的util。使用searchRequestBuilderFactory的AssetPerimpl

我还实现了一个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("");
}

在代码中,应该用“@Reference”注释替换RegistryUtil用法。

如果你对我的例子有任何问题,请告诉我。

 类似资料:
  • bugu-mongo 2.x版本集成了Lucene的功能。当往MongoDB中新增一个Document时,能自动为该Document建立Lucene索引。相应的,当MongoDB中的Document被修改、删除时,对应的Lucene索引也会修改、删除。 另外,bugu-mongo还提供了对Lucene搜索的支持。根据Lucene索引进行搜索的时候,搜索结果能自动转换成对应的Entity对象。 在L

  • 我有一个API,可以对六个字段进行自定义搜索,大致如下,虽然也可能包括敏感数据,因为我在其他地方对相同类型的搜索使用了相同的方法 用户名 电子邮件 名字 姓氏 部门 我通常使用RESTful方法,因此对于用户列表或单个用户,检索用户的过程如下所示 然而,对于搜索,我对如何允许这样做有点困惑。我的初衷是在请求正文中使用JSON,例如 我不能使用请求正文,因为这似乎是合乎逻辑的(和我使用的POST等行

  • 我有大量相同类型的实体,每个实体都有大量属性,并且我只有以下两种选择来存储它们: 将每个项存储在索引中并执行多索引搜索 将所有enties存储在单个索引中,并且只搜索1个索引。 一般而言,我想要一个时间复杂度之间的比较搜索“N”实体与“M”特征在上述每一种情况!

  • 我正在努力让wordpress从页面模板中搜索自定义帖子元。我在互联网上到处找,似乎找不到任何有用的东西。没有插件似乎也能工作。 在我的帖子中,我有一个自定义的meta:“rate”和值:“10”-Wordpress在搜索这些内容时不会给出任何结果。 如果有人能给我写一个搜索页面,我将不胜感激。php页面模板或为我指出正确的方向(我不擅长php)。 以下是我当前的PHP代码:

  • 本节将讨论SQL constraints 和指标。在SQLAlchemy中,键类包括 ForeignKeyConstraint 和 Index . 定义外键 A 外键 在SQL中是一个表级构造,它约束该表中的一个或多个列,使其只允许存在于不同的列集中的值,通常但不总是位于不同的表中。我们称之为约束 外键 列和它们被约束到的列 引用的 柱。被引用的列几乎总是为其所属表定义主键,尽管有例外。外键是连接

  • 我正在使用: neo4j 2.0。1 我有一个具有属性名称的节点人员,我想用Lucene语法搜索该属性。我在我的存储库中使用findByNamelike方法,它非常适合像value*或*value或*etc这样的查询。 但是我需要这样的查询{A*TO D*}。我发现了一个弃用的方法findAllByQuery(名称,查询),用这个方法我可以实现我的需求。 > 我还注意到,如果我从cypher创建节