Menu

Liferay 7.x: Đăng ký thêm loại dữ liệu vào ElasticSearch

Như chúng ta đã biết, ElasticSearch là công cụ tìm kiếm mặc định trên Liferay 7/DXP. Nó có nhiều tính năng nổi bật hơn so với Lucene trên các phiên bản Liferay cũ. Liferay sử dụng ElasticSearch cho mục đích tìm kiếm nội bộ. Ví dụ: Tìm kiếm full-tẽt, phân tích lưu trữ, auto-complete, kiểm tra chính tả, khoảng cách địa lý... Hiện tại, chung ta có thể sử dụng tất cả các tính năng này cho các Entity mà mình tạo ra bằng cách kế thừa các indexer của ElasticSearch. Bài viết này sẽ chỉ cho bạn cách dụng ElasticSearch cho các entity tự tạo.

Đăng ký thêm loại dữ liệu vào ElasticSearch

Các bước triển khai

Bước 1: Tạo mới Entity bằng service builder

Chúng ta sẽ cài đặt các tính năng của ElasticSearch trên một entity tên là "Deal". Ở đây, chúng ta sẻ dụng service builder để tạo ra một entity theo cách thông thường.

<entity local-service="true" name="Deal" remote-service="true" uuid="true">
<column name="dealId" primary="true" type="long" />
<column name="title" type="String" />
<column name="description" type="String" />
<column name="image" type="String" />
<column name="categoryId" type="long" />
<column name="price" type="double" />

<column name="groupId" type="long" />
<column name="companyId" type="long" />
<column name="userId" type="long" />
<column name="userName" type="String" />
<column name="createDate" type="Date" />
<column name="modifiedDate" type="Date" />
</entity>

Bước 2: Tạo một lớp Indexer cho Entity

  • Để thuận tiện, tốt nhất là tạo lớp Indexer có tên trùng với tên của Entity và tạo một package mới trong tầng service
  • Lớp mới này được extends từ lớp trừ tượng BaseIndexer.
@Component(immediate = true, service = Indexer.class)
public class DealIndexer extends BaseIndexer<Deal> {
public static final String CLASS_NAME = DealIndexer.class.getName();
}

Bước 3: Cài đặt constructor của lớp DealIndexer

  • Tạo mới một constructor, nó sẽ thực hiện chọn các trường mặc định để ElasticSearch gọi đến
  • Constructor cũng sẽ đặt quyền để đánh index các kết quả. Nếu chúng ta không thực hiện đặt quyền, ElasticSearch sẽ trả lại tất cả các kết quả phù hợp với điều kiện tìm kiếm bất kể quyền của người dùng trên tài nguyên. Vậy tốt nhất là đặt quyền cho nó.
public DealIndexer() {
setDefaultSelectedFieldNames(
Field.COMPANY_ID,
Field.ENTRY_CLASS_NAME,
Field.ENTRY_CLASS_PK,
Field.GROUP_ID,
Field.MODIFIED_DATE);
setPermissionAware(true);
setFilterSearch(true);
}

Bước 4: Ghi đè phương thực hasPermission

Việc ghi đè phương thức hasPermission để đảm bảo người dùng có quyền VIET có thể lấy được kết quả tìm kiếm của ElasticSearch.

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

return containsPermissions(permissionChecker,
entryClassPK, ActionKeys.VIEW);
}

Bước 5: Ghi đè phương thức doGetSummary

 Phương thức doGetSummary sẽ trả lại thông tin tóm tắt của kết quả tìm kiếm. Chúng ta có thể trả lại tên, tiều đề, nội dung... đảm bảo cho người dùng nhận biết được kết quả.

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

Summary summary = createSummary(document);
summary.setMaxContentLength(200);
return summary;
}

Bước 6: Ghi đè phương thức doGetDocument

Phương thức doGetDocumnent là quan trọng nhất của các lớp Indexer. Nó sẽ định nghĩa những thông tin nào sẽ được thêm vào trong ElasticSearch. Phương thức này sẽ được dùng để lấy kết quả từ ElasticSearch.

@Override
protected Document doGetDocument(Deal deal) throws Exception {
Document document = getBaseModelDocument(Deal.class.getName(), deal);
// Add column to be indexed
document.addNumber("dealId", deal.getDealId());
document.addNumber("dealPrice", deal.getPrice());
document.addNumber("dealTitle", deal.getTitle());
return document;
}

Bước 7: Ghi đè phương thức doReindex

Chúng ta cần phải cài đặt ba phương thức doReindex

  • Phương thức thứ 1: Nó có duy nhất 01 tham số là một đối tượng của Entity. Phương thức này được gọi khi người quản trị thực hiện reindex từ control panel
  • Phương thức thứ 2: Nó có 2 tham số là tên lớp và khoá chính. 
  • Phương thức thứ 3: Nó có 01 tham số là mảng ID của bảng Company. Nó sẽ reindex tất cả các nội dung thuộc các company.
@Override
protected void doReindex(Deal deal) throws Exception {
Document document = getDocument(deal);
indexWriterHelper.updateDocument(
getSearchEngineId(), deal.getCompanyId(),
document, isCommitImmediately());
}

@Override
protected void doReindex(String className, long classPK) throws Exception {
Deal deal = DealLocalServiceUtil.getDeal(classPK);
doReindex(deal);
}

@Override
protected void doReindex(String[] ids) throws Exception {
// here I’ve just reindex single companyIds documents
long companyId = GetterUtil.getLong(ids[0]);
reindexEntries(companyId);
}

Bước 8: Ghi đè phương thức doDelete

Phương thức này sẽ thực hiện xoá các document trong ElasticSearch của một Entity khi Entity đó được xoá.

@Override
protected void doDelete(Deal deal) throws Exception {
deleteDocument(deal.getCompanyId(), deal.getDealId());
}

Tổng kết

Đến đây, Entity của bạn đã sẵn sàng để ElasticSearch đánh Index. Bất cứ khi nào bạn thêm mới, cập nhật hoặc xoá thì ElasticSearch cũng thực hiện công việc tương ứng.  Và nó sẽ xuất hiện trong kết quả tìm kiếm của công cụ.

Bạn có thể đọc bài viết gốc tại đây.

Không có nhận xét nào:

Đăng nhận xét