Foren

How to make custom asset searchable in the search portlet in liferay 7?

thumbnail
Abhishek Jain, geändert vor 7 Jahren.

How to make custom asset searchable in the search portlet in liferay 7?

Regular Member Beiträge: 226 Beitrittsdatum: 20.08.16 Neueste Beiträge
I am able to render the custom asset in the asset publisher and called the method setSearchable (true) inside *AssetRendererFactory. Then too I am not able to search the content of the custom asset. Any idea of how to get results of search for custom asset in liferay 7? Please help.. thanx in advance.
thumbnail
Andrew Jardine, geändert vor 7 Jahren.

RE: How to make custom asset searchable in the search portlet in liferay 7?

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
Hi Abhishek,

Have you defined a custom indexer class for your entity?
thumbnail
Abhishek Jain, geändert vor 7 Jahren.

RE: How to make custom asset searchable in the search portlet in liferay 7?

Regular Member Beiträge: 226 Beitrittsdatum: 20.08.16 Neueste Beiträge
Yes I have defined a custom Indexer. The code is as follows:-

Component(
	    immediate = true,
	    
	    service = Indexer.class
	)

public class SloganIndexer extends BaseIndexer<slogan3> {

    private static final String[] CLASS_NAMES = {Slogan3.class.getName()};

    public SloganIndexer() {
    	setDefaultSelectedFieldNames(
    			Field.ASSET_TAG_NAMES, Field.COMPANY_ID, Field.CONTENT,
    			Field.ENTRY_CLASS_NAME, Field.ENTRY_CLASS_PK, Field.GROUP_ID,
    			Field.MODIFIED_DATE, Field.SCOPE_GROUP_ID, Field.TITLE, Field.UID);
    		setFilterSearch(true);
    		setPermissionAware(true);   
    }

    @Override
    public String[] getClassNames() {
        return CLASS_NAMES;
    }
    
    @Override
	public String[] getSearchClassNames() {
		return new String[] {Slogan3.class.getName()};
	}

   @Override
    public String getPortletId() {
        return "com_example_portlet_SloganAssetRenderermvcportletPortlet";
    }

    @Override
    protected String getPortletId(SearchContext searchContext) {
        return "com_example_portlet_SloganAssetRenderermvcportletPortlet";
    }
    
    /*@Override
    protected void doDelete(Object obj) throws Exception {
        Slogan3 foo = (Slogan3) obj;
        deleteDocument(foo.getCompanyId(), foo.getPrimaryKey());
    }

    @Override
    protected Document doGetDocument(Object obj) throws Exception {

       // AftUtil.debug("FooIndexer:doGetDocument()");
    	System.out.println("from dogetdocument");
    	Slogan3 foo = (Slogan3) obj;

        Document document = getBaseModelDocument("com_example_portlet_SloganAssetRenderermvcportletPortlet", foo);
        document.addText(Field.TITLE, HtmlUtil.extractText("Custom title"));
        document.addText(Field.CONTENT, HtmlUtil.extractText(foo.getSloganText()));

        return document;
    }


    

    
    @Override
	public void doReindex(Object obj) throws Exception {
    	System.out.println("doreindex");
    	Slogan3 entry = (Slogan3) obj;
        Document document = getDocument(entry);

        SearchEngineUtil.updateDocument(getSearchEngineId(),
                entry.getCompanyId(), document);
    }*/

    @Override
    protected void doReindex(String className, long classPK) throws Exception {
    	
        Slogan3 foo = Slogan3LocalServiceUtil.getSlogan3(classPK);
        doReindex(foo);
    }

    @Override
    protected void doReindex(String[] ids) throws Exception {
        try {
            long id = Long.valueOf(ids[0]);
            List<slogan3> entries = Slogan3LocalServiceUtil.getSlogan3s(0,100);

            if (entries.isEmpty()) {
                return;
            }

            Collection<document> documents = new ArrayList<document>();

            for (Slogan3 entry : entries) {
                Document document = getDocument(entry);
                documents.add(document);
            }

            SearchEngineUtil.updateDocuments(getSearchEngineId(), 20116, documents);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /*private void reindexEntries(long companyId) throws Exception {

        int count = SloganLocalServiceUtil.getCompanyEntriesCount(companyId);

        int pages = count / Indexer.DEFAULT_INTERVAL;

        for (int i = 0; i &lt;= pages; i++) {
            int start = (i * Indexer.DEFAULT_INTERVAL);
            int end = start + Indexer.DEFAULT_INTERVAL;

            reindexEntries(companyId, start, end);
        }
    }

    private void reindexEntries(long companyId, int start, int end) throws Exception {

        List<foo> entries = FooLocalServiceUtil.getCompanyEntries(companyId, start, end);

        if (entries.isEmpty()) {
            return;
        }

        Collection<document> documents = new ArrayList<document>();

        for (Foo entry : entries) {
            Document document = getDocument(entry);
            documents.add(document);
        }

        SearchEngineUtil.updateDocuments(getSearchEngineId(), companyId, documents);

    }*/

    private String getContent(Document document) {
        String content = document.get(Field.DESCRIPTION);
        if (Validator.isNull(content)) {
            content = StringUtil.shorten(document.get(Field.CONTENT), 200);
        }
        return content;
    }

	@Override
	public String getClassName() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected Summary doGetSummary(Document document, Locale locale, String snippet, PortletRequest portletRequest,
			PortletResponse portletResponse) throws Exception {
		// TODO Auto-generated method stub
		String title = document.get(Field.TITLE);

        String content = snippet;
        if (Validator.isNull(snippet)) {
            content = getContent(document);
        }
       /* ServiceContext serviceContext = ServiceContextFactory.getInstance(portletRequest);
        String portletId = serviceContext.getPortletId();
        long plid = serviceContext.getPlid();
        String lifecycle = PortletRequest.ACTION_PHASE;
        LiferayPortletURL portletURL = PortletURLFactoryUtil.create(portletRequest, portletId, plid, lifecycle);
        String entryId = document.get(Field.ENTRY_CLASS_PK);
        portletURL.setParameter("jspPage", "/view.jsp");
        portletURL.setParameter(AftConstants.FOO_ID, entryId);*/
        
        return new Summary(title, content);
	}

	@Override
	protected void doDelete(Slogan3 object) throws Exception {
		// TODO Auto-generated method stub
		deleteDocument(object.getCompanyId(), object.getPrimaryKey());
		
	}

	@Override
	protected Document doGetDocument(Slogan3 object) throws Exception {
		// TODO Auto-generated method stub
		Document document = getBaseModelDocument(Slogan3.class.getName(), object);
        document.addText(Field.TITLE, HtmlUtil.extractText("Custom title"));
        document.addText(Field.CONTENT, HtmlUtil.extractText(object.getSloganText()));

        return document;
	}

	@Override
	protected void doReindex(Slogan3 object) throws Exception {
		// TODO Auto-generated method stub
		 Document document = doGetDocument(object);
		 document.add(new Field(Field.GROUP_ID,Long.toString(object.getGroupId())));
		 document.add(new Field(Field.SCOPE_GROUP_ID,Long.toString(object.getGroupId())));
		 document.add(new Field(Field.STATUS,Long.toString(0L))); 
	        SearchEngineUtil.updateDocument(getSearchEngineId(),
	        		object.getCompanyId(), document);
	        
	        
	}
	
	@Override
	public void postProcessContextBooleanFilter(
			BooleanFilter contextBooleanFilter, SearchContext searchContext)
		throws Exception {

		addStatus(contextBooleanFilter, searchContext);
	}

}

</document></document></foo></document></document></slogan3></slogan3>
thumbnail
Abhishek Jain, geändert vor 7 Jahren.

RE: How to make custom asset searchable in the search portlet in liferay 7? (Antwort)

Regular Member Beiträge: 226 Beitrittsdatum: 20.08.16 Neueste Beiträge
I am able to make my custom asset searchable by changing the Indexer file. The changed code is as follows:-



package com.example.service.impl;

import com.example.model.Slogan3;
import com.example.service.Slogan3LocalService;
import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.IndexableActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.Property;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.search.BaseIndexer;
import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.IndexWriterHelperUtil;
import com.liferay.portal.kernel.search.Indexer;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.Summary;
import com.liferay.portal.kernel.search.filter.BooleanFilter;
import com.liferay.portal.kernel.security.permission.PermissionChecker;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.workflow.WorkflowConstants;

import java.util.Date;
import java.util.Locale;

import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * @author Brian Wing Shun Chan
 * @author Harry Mark
 * @author Bruno Farache
 * @author Raymond Augé
 */
@Component(immediate = true, service = Indexer.class)
public class SloganIndexer extends BaseIndexer<slogan3> {

	public static final String CLASS_NAME = Slogan3.class.getName();

	public SloganIndexer() {
		setDefaultSelectedFieldNames(
			Field.ASSET_TAG_NAMES, Field.COMPANY_ID, Field.CONTENT,
			Field.ENTRY_CLASS_NAME, Field.ENTRY_CLASS_PK, Field.GROUP_ID,
			Field.MODIFIED_DATE, Field.SCOPE_GROUP_ID, Field.TITLE, Field.UID);
		setFilterSearch(true);
		setPermissionAware(true);
	}

	@Override
	public String getClassName() {
		return CLASS_NAME;
	}
	
	

	@Override
	public boolean hasPermission(
			PermissionChecker permissionChecker, String entryClassName,
			long entryClassPK, String actionId)
		throws Exception {

		return true;
	}

	@Override
	public boolean isVisible(long classPK, int status) throws Exception {
		

		return true;
	}

	@Override
	public void postProcessContextBooleanFilter(
			BooleanFilter contextBooleanFilter, SearchContext searchContext)
		throws Exception {

		addStatus(contextBooleanFilter, searchContext);
	}

	

	@Override
	protected Document doGetDocument(Slogan3 blogsEntry) throws Exception {
		Document document = getBaseModelDocument(CLASS_NAME, blogsEntry);

		//document.addText(Field.CAPTION, blogsEntry.getCoverImageCaption());
		
        document.addText(Field.TITLE, HtmlUtil.extractText("Slogan Contest Entry"));
        document.addText(Field.CONTENT, HtmlUtil.extractText(blogsEntry.getSloganText()));

        return document;
	}

	@Override
	protected Summary doGetSummary(
		Document document, Locale locale, String snippet,
		PortletRequest portletRequest, PortletResponse portletResponse) {

		Summary summary = createSummary(document);

		summary.setMaxContentLength(200);

		return summary;
	}

	@Override
	protected void doReindex(Slogan3 blogsEntry) throws Exception {
		Document document = getDocument(blogsEntry);
		 document.add(new Field(Field.GROUP_ID,Long.toString(blogsEntry.getGroupId())));
		 document.add(new Field(Field.SCOPE_GROUP_ID,Long.toString(blogsEntry.getGroupId())));
		 document.add(new Field(Field.STATUS,Long.toString(0L))); 
		IndexWriterHelperUtil.updateDocument(
			getSearchEngineId(), blogsEntry.getCompanyId(), document,
			isCommitImmediately());
	}

	@Override
	protected void doReindex(String className, long classPK) throws Exception {
		Slogan3 entry = _blogsEntryLocalService.getSlogan3(classPK);

		doReindex(entry);
	}

	@Override
	protected void doReindex(String[] ids) throws Exception {
		long companyId = GetterUtil.getLong(ids[0]);

		reindexEntries(companyId);
	}

	protected void reindexEntries(long companyId) throws PortalException {
		final IndexableActionableDynamicQuery indexableActionableDynamicQuery =
			_blogsEntryLocalService.getIndexableActionableDynamicQuery();

		indexableActionableDynamicQuery.setAddCriteriaMethod(
			new ActionableDynamicQuery.AddCriteriaMethod() {

				@Override
				public void addCriteria(DynamicQuery dynamicQuery) {
					Property displayDateProperty = PropertyFactoryUtil.forName(
						"displayDate");

					dynamicQuery.add(displayDateProperty.lt(new Date()));

					Property statusProperty = PropertyFactoryUtil.forName(
						"status");

					Integer[] statuses = {
						WorkflowConstants.STATUS_APPROVED,
						WorkflowConstants.STATUS_IN_TRASH
					};

					dynamicQuery.add(statusProperty.in(statuses));
				}

			});
		indexableActionableDynamicQuery.setCompanyId(companyId);
		indexableActionableDynamicQuery.setPerformActionMethod(
			new ActionableDynamicQuery.PerformActionMethod<slogan3>() {

				@Override
				public void performAction(Slogan3 entry) {
					try {
						Document document = getDocument(entry);

						indexableActionableDynamicQuery.addDocuments(document);
					}
					catch (PortalException pe) {
						if (_log.isWarnEnabled()) {
							_log.warn(
								"Unable to index blogs entry " +
									entry.getSloganId()+1,
								pe);
						}
					}
				}

			});
		indexableActionableDynamicQuery.setSearchEngineId(getSearchEngineId());

		indexableActionableDynamicQuery.performActions();
	}

	@Reference(unbind = "-")
	protected void setBlogsEntryLocalService(
			Slogan3LocalService blogsEntryLocalService) {

		_blogsEntryLocalService = blogsEntryLocalService;
	}

	private static final Log _log = LogFactoryUtil.getLog(
		SloganIndexer.class);

	private Slogan3LocalService _blogsEntryLocalService;

	@Override
	protected void doDelete(Slogan3 object) throws Exception {
		// TODO Auto-generated method stub
		deleteDocument(object.getCompanyId(), object.getPrimaryKey());
		
	}
	
	

}
</slogan3></slogan3>


Hope, this might help someone.. emoticon
Ketan Solanki, geändert vor 6 Jahren.

RE: How to make custom asset searchable in the search portlet in liferay 7?

Junior Member Beiträge: 63 Beitrittsdatum: 28.05.14 Neueste Beiträge
Hi Abhishek,

I understand that this post has been old enough but just in case you stumble upon this then please answer my question.

As I have read, to prepare the model/services, I have to use service builder which would create all the classes for me. For Reference, https://web.liferay.com/community/forums/-/message_boards/message/93312027.

Please confirm that you had taken the same approach. If you had taken any other approach then please let me know.

Thanks,
Ketan
thumbnail
Liferay Dev, geändert vor 6 Jahren.

RE: How to make custom asset searchable in the search portlet in liferay 7?

Junior Member Beiträge: 81 Beitrittsdatum: 17.05.15 Neueste Beiträge
Hi Abhishek,

I am getting this issue
"non-static variable _sloganLocalService cannot be referenced from a static context"

One question the where you kept the indexer class in web or service only.

Please give suggestions.

Thanks in advance.
thumbnail
Andrew Jardine, geändert vor 6 Jahren.

RE: How to make custom asset searchable in the search portlet in liferay 7?

Liferay Legend Beiträge: 2416 Beitrittsdatum: 22.12.10 Neueste Beiträge
If you are using Liferay 7, where you put the class is more a matter of style or logical semantics I think rather than necessity. For me, I would put it in the service module because you it's part of the data management piece so if I am looking for an indexer class for CustomEntityXXX, that is where I would think to look for it first. With that said, more important than where you put it, I think, is the naming convention you use. Using the term CustomEntityXXXIndexer (postfix with indexer) means that it would easily be found using any IDE with a class lookup function.

Your error that you are referencing doesn't look like an issue with which module your class is in to me. That error is normally the result of having a non-static variable being referenced from a method marked as static. Maybe if you provide us the code (class) that is generating that error we can help identify the culprit.
thumbnail
Liferay Dev, geändert vor 6 Jahren.

RE: How to make custom asset searchable in the search portlet in liferay 7?

Junior Member Beiträge: 81 Beitrittsdatum: 17.05.15 Neueste Beiträge
final IndexableActionableDynamicQuery indexableActionableDynamicQuery =
UserProfileLocalServiceUtil.getIndexableActionableDynamicQuery();

here the getIndexableActionableDynamicQuery() method is not able to find.. Is there anything i missed.

Service.xml : <entity name="UserProfile" local-service="true" remote-service="true">

Indexeer Class:
package com.schneider.eds.search.indexer;(Not in service module)
@Component(immediate = true, service = Indexer.class)
public class UserProfileIndexer extends BaseIndexer<UserProfile>{
///code goes here
}