Message Boards

Search programmatically in custom REST Portlet

Uwe Peters, modified 4 Years ago.

Search programmatically in custom REST Portlet

New Member Posts: 22 Join Date: 11/24/20 Recent Posts

How can I search programmatically in my own portlet in liferay 7.2 CE? 

Is there a Service for that? I want to search like the default liferay search on the /search page. This means I only have one search parameter.

Is there any easy way to do this? Which Service do I need to import and do I need any gradle dependencies?

I want to return the search result as JSON in my REST Portlet.

Uwe Peters, modified 4 Years ago.

RE: Search programmatically in custom REST Portlet

New Member Posts: 22 Join Date: 11/24/20 Recent Posts

I cant find any solution for this except a dynamic query over the asset table. But this would bypass the search engine from liferay.

I dont know who to ask anymore, is there anyone who can help me with that? 

I just want to serve the liferay default search via REST and JSON.

thumbnail
Christoph Rabel, modified 4 Years ago.

RE: Search programmatically in custom REST Portlet

Liferay Legend Posts: 1555 Join Date: 9/24/09 Recent Posts

You can search directly, you can find some sample code in the "Providing a Search Mechanism" part:

https://help.liferay.com/hc/en-us/articles/360018179251-Implementing-Search-and-Indexing

Uwe Peters, modified 4 Years ago.

RE: RE: Search programmatically in custom REST Portlet

New Member Posts: 22 Join Date: 11/24/20 Recent Posts

Thanks for the answer. I will look into it. But you link directs me to some Liferay 6.2 article is this still the way to go? 

I was also wondering if there is any chance to use default behaviour from the liferay search page with REST. Because if I implement it myself I have to add and remove filters and so on for my custom search method myself too.

Everything I want to use is already in the default search page but it is limited to some jsp views. I know that I can override them but this would still result in a page refresh on every search query/filter toggle.

Jan Tošovský, modified 4 Years ago.

RE: Search programmatically in custom REST Portlet

Liferay Master Posts: 576 Join Date: 7/22/10 Recent Posts

If you want to return any asset type matching your keywords, just build the SearchRequest specifying your keywords. In this example I am reducing the results just to selected documentIds. That documentId is a field of my custom asset type. 

I was trying to build this query using former search API, but I was faced with some class clashes when specifying my terms filter. I rewrote it using new API and those issues have gone. 

So put this dependency to your module:

<dependency>
    <groupId>com.liferay</groupId>
    <artifactId>com.liferay.portal.search.api</artifactId>
    <scope>provided</scope>
</dependency>

And then use something like this
 

@Component(
        property = {
                JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE + "=/myapp",
                JaxrsWhiteboardConstants.JAX_RS_NAME + "=MyApp.Rest"
        },
        service = Application.class
)
public class MyRestApplication extends Application {

    @Reference
    protected Queries queries;

    @Reference
    protected Searcher searcher;

    @Reference
    protected SearchRequestBuilderFactory searchRequestBuilderFactory;

    ...
    
    private String getSearchResultsContent(List<Long> selectedDocumentIdList, String keywords, int start, HttpServletRequest request) {

        String content = null;

        try {
            long companyId = PortalUtil.getCompanyId(request);

            SearchRequestBuilder searchRequestBuilder = searchRequestBuilderFactory.builder();
            searchRequestBuilder.withSearchContext(
                    searchContext -> {
                        searchContext.setCompanyId(companyId);
                        searchContext.setKeywords(keywords);
                    });
            searchRequestBuilder.from(start);
            searchRequestBuilder.size(20);
            searchRequestBuilder.highlightEnabled(true);

            TermsQuery termsQuery = queries.terms("documentId");
            for (Long documentId : selectedDocumentIdList) {
                termsQuery.addValue(documentId.toString());
            }

            SearchRequest searchRequest = searchRequestBuilder.query(termsQuery).build();
            SearchResponse searchResponse = searcher.search(searchRequest);

            for (SearchHit hit : searchResponse.getSearchHits().getSearchHits()) {
            }


        } catch (Exception exception) {
            ...
        }

        return content;
    }
};
Uwe Peters, modified 4 Years ago.

RE: RE: Search programmatically in custom REST Portlet

New Member Posts: 22 Join Date: 11/24/20 Recent Posts

Hey thanks for the code snipped that helped a lot!

I feared that I have to implement it like that, I hoped that there is a REST api for searching just like the liferay implemented search site :(.