Liferay Indexing and search

I was thinking it wouldn't take me a lot of time to Indexing and search, because all codes are on the book. I just need to copy, past and change. The main problem is liferay version. In the book, it use 6.0, when we add entity, we don't need to reindex(), it'll call implicitly I assume since the code doesn't add. But it doesn't work on version 6.1. I didn't notice that and missed it. The result is I spent almost half day on that.

Let's implement indexing and search step by step.

1. We need to configure our own indexer class in liferay-portlet.xml like this:

<portlet>
<portlet-name>BookServiceBuilder</portlet-name>
<icon>/icon.png</icon>
<indexer-class>
com.rujuan.book.search.BookIndexer
</indexer-class>

...more

2. write your own implementation of Indexer

package com.rujuan.book.search;


import com.liferay.portal.kernel.search.BaseIndexer;
import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.DocumentImpl;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.SearchEngineUtil;
import com.liferay.portal.kernel.search.Summary;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portlet.asset.model.AssetCategory;
import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
import com.rujuan.book.model.Book;
import com.rujuan.book.service.BookLocalServiceUtil;
import com.rujuan.book.util.WebKeys;


import java.util.List;
import java.util.Locale;


import javax.portlet.PortletURL;


import org.apache.log4j.Logger;


public class BookIndexer extends BaseIndexer {
public static final String[] CLASS_NAMES = { Book.class.getName() };
public static final String PORTLET_ID = WebKeys.BOOK_PORTLET_ID;
Logger logger = Logger.getLogger(BookIndexer.class);

@Override
public String[] getClassNames() {
logger.info("get class names..");
return CLASS_NAMES;
}

@Override
public String getPortletId() {
logger.info("get portlet id..");
return PORTLET_ID;
}

@Override
protected String getPortletId(SearchContext arg0) {
logger.info("get portlet id..SearchContext");
return PORTLET_ID;
}

@Override
protected void doDelete(Object obj) throws Exception {
logger.info("do delete..");
Book book = (Book) obj;
Document document = new DocumentImpl();
document.addUID(this.getPortletId(), book.getPrimaryKey());
SearchEngineUtil.deleteDocument(book.getCompanyId(), document.get(Field.UID));
}

@Override
protected Document doGetDocument(Object obj) throws Exception {
logger.info("do get document...");
Book book = (Book) obj;
long companyId = book.getCompanyId();
long groupId = getParentGroupId(book.getGroupId());
long scopeGroupId = book.getGroupId();
long userId = book.getUserId();
long resourcePrimKey = book.getPrimaryKey();
String title = book.getTitle();
String summary = book.getSummary();
String authorName = book.getAuthorname();

long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
Book.class.getName(), resourcePrimKey);

List<AssetCategory> categories = AssetCategoryLocalServiceUtil.getCategories(
Book.class.getName(), resourcePrimKey);

String[] assetCategoryNames = StringUtil.split(ListUtil.toString(categories, "name"));
String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
           Book.class.getName(), resourcePrimKey);
Document document = new DocumentImpl();
document.addUID(this.getPortletId(), resourcePrimKey);
document.addKeyword(Field.COMPANY_ID, companyId);
document.addKeyword(Field.PORTLET_ID, getPortletId());
document.addKeyword(Field.GROUP_ID, groupId);
document.addKeyword(Field.SCOPE_GROUP_ID, scopeGroupId);
document.addKeyword(Field.USER_ID, userId);
document.addText(Field.TITLE, title);
document.addText(Field.CONTENT, authorName);
document.addText(Field.DESCRIPTION, summary);
document.addKeyword(Field.TITLE, title);

document.addKeyword(Field.ASSET_CATEGORY_IDS, assetCategoryIds);
document.addKeyword("assetCategoryNames", assetCategoryNames);
// document.addKeyword(Field.ASSET_CATEGORY_NAMES, assetCategoryNames);
document.addKeyword(Field.ASSET_TAG_NAMES, assetTagNames);

document.addKeyword(Field.ENTRY_CLASS_NAME, Book.class.getName());
document.addKeyword(Field.ENTRY_CLASS_PK, resourcePrimKey);
return document;
}

@Override
protected Summary doGetSummary(Document document, Locale arg1, String snippet,
PortletURL portletURL) throws Exception {
logger.info("do get summary..");
String title = document.get(Field.TITLE);
String content = snippet;
if (Validator.isNull(snippet)) {
content = document.get(Field.DESCRIPTION);
if (Validator.isNull(content)) {
content = document.get(Field.CONTENT);
}
}
String resourcePrimKey = document.get(Field.ENTRY_CLASS_PK);
portletURL.setParameter("jspPage", "/view_book.jsp");
portletURL.setParameter("resourcePrimKey", resourcePrimKey);
return new Summary(title, content, portletURL);
}

@Override
protected void doReindex(Object obj) throws Exception {
logger.info("do reindex...1");
Book book = (Book) obj;
SearchEngineUtil.updateDocument(book.getCompanyId(), doGetDocument(book));
}

@Override
protected void doReindex(String[] ids) throws Exception {
logger.info("do reindex...2");
long companyId = GetterUtil.getLong(ids[0]);
// unimplemented
}

@Override
protected void doReindex(String arg0, long classPK) throws Exception {
logger.info("do reindex...3");
Book book = BookLocalServiceUtil.getBook(classPK);
doReindex(book);
}
}


3. Now it's time for us to write JSPs, first we add a page to input our keywords:

<%
String currentURL = PortalUtil.getCurrentURL(request);
%>
<liferay-portlet:renderURL varImpl="searchURL">
<portlet:param name="jspPage" value="/search.jsp" />
</liferay-portlet:renderURL>
<aui:form action="<%=searchURL%>" method="get" name="fm0">
<liferay-portlet:renderURLParams varImpl="searchURL" />
<aui:input name="redirect" type="hidden" value="<%= currentURL %>" />
<aui:input name="groupId" type="hidden" value="10180"/>
<div class="portlet-toolbar search-form">
<span class="aui-search-bar"> 
<aui:input inlineField="<%=true%>" label="" name="keywords" size="30" title="search-entries" type="text" /> 
<aui:button type="submit" value="search" />
</span>
</div>
</aui:form>


4. Now it's coming to our key jsps, it's the page to show results.

<%--
/**
 * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */
--%>


<%@ include file="init.jsp"%>


<%
String redirect = ParamUtil.getString(request, "redirect");
String keywords = ParamUtil.getString(request, "keywords");
%>
<portlet:renderURL var="homeURL">

</portlet:renderURL>
<liferay-portlet:renderURL varImpl="searchURL">
<portlet:param name="jspPage" value="/search.jsp" />
</liferay-portlet:renderURL>


<aui:form action="<%=searchURL%>" method="get" name="fm">
<liferay-portlet:renderURLParams varImpl="searchURL" />
<aui:input name="redirect" type="hidden" value="<%=redirect%>" />


<liferay-ui:header backURL="<%=homeURL%>" title="search" />


<%
PortletURL portletURL = renderResponse.createRenderURL();


portletURL.setParameter("jspPage", "/search.jsp");
portletURL.setParameter("redirect", redirect);
portletURL.setParameter("keywords", keywords);


List<String> headerNames = new ArrayList<String>();


headerNames.add("#");
headerNames.add("title");
headerNames.add("author");
headerNames.add("summary");


SearchContainer searchContainer = new SearchContainer(renderRequest, null, null,
SearchContainer.DEFAULT_CUR_PARAM, SearchContainer.DEFAULT_DELTA,
portletURL, headerNames, LanguageUtil.format(pageContext,
"no-entries-were-found-that-matched-the-keywords-x", "<strong>"
+ HtmlUtil.escape(keywords) + "</strong>"));


try {
Indexer indexer = IndexerRegistryUtil.getIndexer(Book.class);
SearchContext searchContext = SearchContextFactory.getInstance(request);

searchContext.setStart(searchContainer.getStart());
searchContext.setKeywords(keywords);
searchContext.setEnd(searchContainer.getEnd());

Hits results = indexer.search(searchContext);


int total = results.getLength();
searchContainer.setTotal(total);


List resultRows = searchContainer.getResultRows();


for (int i = 0; i < results.getDocs().length; i++) {
Document doc = results.doc(i);


ResultRow row = new ResultRow(doc, i, i);


// Position


row.addText(searchContainer.getStart() + i + 1 + StringPool.PERIOD);


// Book
long bookId = GetterUtil.getLong(doc.get(Field.ENTRY_CLASS_PK));


Book book = null;


try {
book = BookLocalServiceUtil.getBook(bookId);
book = book.toEscapedModel();


} catch (Exception e) {
if (_log.isWarnEnabled()) {
_log.warn("Book search index is stale and contains entry " + bookId);
}


continue;
}


PortletURL rowURL = renderResponse.createRenderURL();


rowURL.setParameter("jspPage", "/view_book.jsp");
rowURL.setParameter("redirect", currentURL);
rowURL.setParameter("resourcePrimKey", String.valueOf(book.getBookid()));


row.addText(book.getTitle());
row.addText(book.getAuthorname());
row.addText(book.getSummary());


resultRows.add(row);
}
%>


<span class="aui-search-bar"> <aui:input inlineField="<%=true%>"
label="" name="keywords" size="30" title="search-entries" type="text"
value="<%=keywords%>" /> <aui:button type="submit" value="search" />
</span>


<br />
<br />


<liferay-ui:search-iterator searchContainer="<%=searchContainer%>" />


<%
} catch (Exception e) {
_log.error(e.getMessage());
}
%>
</aui:form>


<%
if (Validator.isNotNull(keywords)) {
PortalUtil.addPortletBreadcrumbEntry(request,
LanguageUtil.get(pageContext, "search") + ": " + keywords, currentURL);
}
%>


<%!private static Log _log = LogFactoryUtil.getLog("BookServiceBuilder.docroot.search_jsp");%>


6. If you do that, it won't work well. The problem is like what I mentioned above. so go to our BookLocalServiceImpl.

public Book addBook(Book newBook, long userId, ServiceContext serviceContext)
throws SystemException, PortalException {


Book book = bookPersistence.create(newBook.getBookid());
book.setCompanyId(newBook.getCompanyId());
book.setGroupId(newBook.getGroupId());
book.setUserId(newBook.getUserId());
book.setTitle(newBook.getTitle());
book.setAuthorname(newBook.getAuthorname());
book.setIsbn(newBook.getIsbn());
book.setSummary(newBook.getSummary());
bookPersistence.update(book, false);

Indexer indexer = IndexerRegistryUtil.getIndexer(Book.class);
indexer.reindex(book);



return book;
}


Now all work are done, we just need to do "ant build-service" then deploy. Go and see magic happens!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值