參考資料:
http://blog.csdn.net/smile_juan/article/details/8117497
1. 我們需要先在 liferay-portlet.xml 加入自己indexer的class
<portlet>
<portlet-name>BookServiceBuilder</portlet-name>
<icon>/icon.png</icon>
<indexer-class>
com.xxx.xxx.xxx.ProjetIndexer</indexer-class>
...more
2. 開始實作indexer 的類別
import java.util.List;
import java.util.Locale;
import javax.portlet.PortletURL;
import com.fansysoft.danny.model.MyData;
import com.fansysoft.danny.service.MyDataLocalServiceUtil;
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.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.portal.kernel.util.WebKeys;
import com.liferay.portal.service.ClassNameLocalServiceUtil;
import com.liferay.portal.util.PortletKeys;
import com.liferay.portlet.asset.model.AssetCategory;
import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
public class ProjetIndexer extends BaseIndexer{
public static final String[] CLASS_NAMES = { MyData.class.getName() };
public static final String PORTLET_ID = WebKeys.PORTLET_ID;
Log logger = LogFactoryUtil.getLog(ProjetIndexer.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..");
MyData book = (MyData) 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...");
MyData MyData = (MyData) obj;
long companyId = MyData.getCompanyId();
long groupId = getParentGroupId(MyData.getGroupId());
long scopeGroupId = MyData.getGroupId();
long userId = MyData.getUserId();
long resourcePrimKey = MyData.getPrimaryKey();
String myDataId = String.valueOf(MyData.getMydataId());
String myDataName = MyData.getUserName();
String myDataAge = String.valueOf(MyData.getUserAge());
String myDataPhone = MyData.getUserPhone();
String myDataEmail = MyData.getUserEmail();
String myDataCreateDate = MyData.getCreateDate().toString();
long[] assetCategoryIds = AssetCategoryLocalServiceUtil.getCategoryIds(
MyData.class.getName(), resourcePrimKey);
List<AssetCategory> categories = AssetCategoryLocalServiceUtil
.getCategories(MyData.class.getName(), resourcePrimKey);
String[] assetCategoryNames = StringUtil.split(ListUtil.toString(
categories, "name"));
String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
MyData.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.CLASS_PK, myDataId);
document.addText(Field.USER_NAME, myDataName);
document.addText(Field.CONTENT, myDataAge);
document.addText(Field.DESCRIPTION, myDataPhone);
document.addText(Field.SNIPPET, myDataEmail);
document.addText(Field.CREATE_DATE, myDataCreateDate);
// 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, MyData.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", "/html/indexer/view.jsp");
portletURL.setParameter("resourcePrimKey", resourcePrimKey);
return new Summary(title, content, portletURL);
}
@Override
protected void doReindex(Object obj) throws Exception {
logger.info("do reindex...1");
MyData book = (MyData) 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");
MyData book = MyDataLocalServiceUtil.getMyData(classPK);
doReindex(book);
}
}
3. 簡單做個jsp 可以讓你輸入keywords 的欄位
view.jsp
<%@include file="/html/indexer/init.jsp" %>
<liferay-portlet:renderURL varImpl="searchURL">
<portlet:param name="jspPage" value="/html/indexer/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.再來做一個取得keywords之後 顯示結果的jsp
search.jsp
<%@ include file="/html/indexer/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="/html/indexer/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", "/html/indexer/search.jsp");
portletURL.setParameter("redirect", redirect);
portletURL.setParameter("keywords", keywords);
List<String> headerNames = new ArrayList<String>();
headerNames.add("#");
headerNames.add("Name");
headerNames.add("Age");
headerNames.add("Phone");
headerNames.add("Email");
headerNames.add("CreateDate");
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(MyData.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));
MyData book = null;
try {
book = MyDataLocalServiceUtil.getMyData(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", "/html/indexer/view.jsp");
rowURL.setParameter("redirect", currentURL);
rowURL.setParameter("resourcePrimKey",
String.valueOf(book.getMydataId()));
row.addText(book.getUserName());
row.addText(String.valueOf(book.getUserAge()));
row.addText(book.getUserPhone());
row.addText(book.getUserEmail());
row.addText(book.getCreateDate().toString());
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("ContentManagment.docroot.html.indexer.search_jsp");%>
5. 再來就去實作 自己model的impl 的addxxx{ }
MyDataLocalServiceImpl.
public MyData addMyData(MyData newMyData, long userId,
ServiceContext serviceContext) throws SystemException,
PortalException {
MyData myData = myDataPersistence.create(counterLocalService
.increment(MyData.class.getName()));
myData.setCompanyId(newMyData.getCompanyId());
myData.setGroupId(newMyData.getGroupId());
myData.setUserId(serviceContext.getUserId());
myData.setUserName(newMyData.getUserName());
myData.setUserAge(newMyData.getUserAge());
myData.setUserPhone(newMyData.getUserPhone());
myData.setUserEmail(newMyData.getUserEmail());
myData.setCreateDate(newMyData.getCreateDate());
myData.setModifiedDate(newMyData.getModifiedDate());
myData.setStatus(WorkflowConstants.STATUS_DRAFT);
myDataPersistence.update(myData, false);
Indexer indexer = IndexerRegistryUtil.getIndexer(MyData.class);
indexer.reindex(myData);return myData;
}
6. 這是我的 service.xml 可供參考
<service-builder package-path="com.xxx.xxx.xxx">
<author>yourName</author>
<namespace>yourNS</namespace>
<entity name="MyData" uuid="true" local-service="true" remote-service="false">
<!-- PK fields -->
<column name="mydataId" type="long" primary="true" />
<!-- Audit fields -->
<column name="userName" type="String" />
<column name="userAge" type="int" />
<column name="userPhone" type="String" />
<column name="userEmail" type="String" />
<column name="createDate" type="Date" />
<column name="modifiedDate" type="Date" />
<column name="status" type="int" />
<column name="statusByUserId" type="long" />
<column name="statusByUserName" type="String" />
<column name="statusDate" type="Date" />
<column name="companyId" type="long" />
<column name="groupId" type="long" />
<column name="userId" type="long" />
<order>
<order-column name="userId" order-by="asc"/>
<order-column name="modifiedDate" order-by="desc"/>
</order>
<!-- Finder methods -->
<finder name="userId" return-type="MyData">
<finder-column name="userId"/>
</finder>
<finder name="userName" return-type="Collection">
<finder-column name="userName" />
</finder>
<finder name="userAge" return-type="Collection">
<finder-column name="userAge"/>
</finder>
<reference package-path="com.liferay.portal" entity="User" />
<reference package-path="com.liferay.portlet.asset" entity="AssetEntry" />
<reference package-path="com.liferay.portlet.ratings" entity="RatingsStats" />
</entity>