Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
RE: Elasticsearch Custom users indexing errors
Hi everyone !I've followed the tutorial about indexing content for Elasticsearch. I did so for users in order to make a custom directory app with a search engine based on indexed users by Elasticsearch.
Everything seems to work fine except for a problem : I can't see users anymore in Liferay's admin part of the portal. I can only see connected Administrator, but it's the only one displayed while I have a lot more users.
I wondered if this is linked to permissions or something like that ? I made a classical indexer (like in the tutorial) and only changed the "doGetDocument" method.
Thanks in advance !
Everything seems to work fine except for a problem : I can't see users anymore in Liferay's admin part of the portal. I can only see connected Administrator, but it's the only one displayed while I have a lot more users.
I wondered if this is linked to permissions or something like that ? I made a classical indexer (like in the tutorial) and only changed the "doGetDocument" method.
Thanks in advance !
Hi Nils,
What Liferay version are you using?
Did you created a custom indexer for User entity, or it was a custom one?
Users and groups in Liferay admin section are retrieved from Elasticsearch index, if you have changed the way it stores the data, perhaps you have broken out-of-the-box functionality.
What Liferay version are you using?
Did you created a custom indexer for User entity, or it was a custom one?
Users and groups in Liferay admin section are retrieved from Elasticsearch index, if you have changed the way it stores the data, perhaps you have broken out-of-the-box functionality.
Hi Jorge,Sorry for being late ! I'm on Liferay Community 7.1 GA3 ; and I created a custom UserIndexerPostProcessor based on the tutorial provided by Liferay Team.
Here is the code :
/**
* @author Liferay
*/
@Component(
immediate = true,
property = {
"indexer.class.name=com.liferay.portal.kernel.model.User"
},
service = IndexerPostProcessor.class
)
public class UserIndexerPostProcessor implements IndexerPostProcessor {
@Override
public void postProcessContextBooleanFilter(
BooleanFilter booleanFilter, SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessContextBooleanFilter");
}
}
@Override
public void postProcessContextQuery(
BooleanQuery contextQuery, SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessContextQuery");
}
}
@Override
public void postProcessDocument(Document document, Object obj)
throws Exception {
ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();
Field userIdField = document.getField("entryClassPK");
String userId = userIdField.getValue();
User user = UserLocalServiceUtil.getUser(Long.parseLong(userId));
Field organizationIdsField = document.getField("organizationIds");
String[] organizations = organizationIdsField.getValues();
Contact contact = user.getContact();
List<Address> addresses = AddressLocalServiceUtil.getAddresses(user.getCompanyId(), "com.liferay.portal.kernel.model.Contact", contact.getContactId());
String[] fieldsToRemove = {"modified", "modified_sortable", "firstName_sortable", "groupId", "screenName", "scopeGroupId",
"organizationIds", "country", "entryClassPK"};
document = this.removeFields(document, fieldsToRemove);
document.addText("jobTitle", user.getJobTitle());
document.addText("country", addresses.get(0).getCountry().getName());
document.addText("id", userId);
document.addText("avatar", user.getPortraitURL(serviceContext.getThemeDisplay()));
try {
Field fPhones = new Field("phones");
List<Phone> phones = PhoneServiceUtil.getPhones("P", contact.getContactId());
for (Phone phone : phones) {
Field pNumber = new Field("number");
pNumber.setValue(phone.getNumber());
pNumber.setSortable(false);
pNumber.setParentField(fPhones);
Field pType = new Field("type");
pType.setValue(phone.getType().getName());
pType.setSortable(false);
pType.setParentField(fPhones);
Field pPrimary = new Field("primary");
pPrimary.setValue(String.valueOf(phone.isPrimary()));
pPrimary.setSortable(false);
pPrimary.setParentField(fPhones);
}
document.add(fPhones);
} catch(Exception e) {
e.printStackTrace();
}
Field fOrga = new Field("organisations");
List<Organization> organizations1 = OrganizationServiceUtil.getUserOrganizations(user.getUserId());
for (Organization orga : organizations1) {
Field oId = new Field("id");
oId.setValue(String.valueOf(orga.getOrganizationId()));
oId.setSortable(false);
oId.setParentField(fOrga);
Field oName = new Field("type");
oName.setValue(orga.getType());
oName.setSortable(false);
oName.setParentField(fOrga);
Field oprimary = new Field("primary");
oprimary.setValue(String.valueOf(orga.isRoot()));
oprimary.setSortable(false);
oprimary.setParentField(fOrga);
}
Field fMails = new Field("mails");
List<EmailAddress> mails = EmailAddressServiceUtil.getEmailAddresses("User", user.getUserId());
for (EmailAddress mail : mails) {
Field mMail = new Field("mail");
mMail.setValue(mail.getAddress());
mMail.setSortable(false);
mMail.setParentField(fMails);
Field mType = new Field("type");
mType.setValue(mail.getType().getName());
mType.setSortable(false);
mType.setParentField(fMails);
}
document.add(fMails);
String[] streets = {};
streets[0] = user.getAddresses().get(0).getStreet1();
streets[1] = user.getAddresses().get(0).getStreet2();
streets[2] = user.getAddresses().get(0).getStreet3();
document.addText("street", streets);
document.addText("isExecutive", "TODO");
if (_log.isInfoEnabled()) {
_log.info("postProcessDocument");
}
}
@Override
public void postProcessFullQuery(
BooleanQuery fullQuery, SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessFullQuery");
}
}
@Override
public void postProcessSearchQuery(
BooleanQuery searchQuery, BooleanFilter booleanFilter,
SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessSearchQuery");
}
}
@Override
public void postProcessSearchQuery(
BooleanQuery searchQuery, SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessSearchQuery");
}
}
@Override
public void postProcessSummary(
Summary summary, Document document, Locale locale, String snippet) {
if (_log.isInfoEnabled()) {
_log.info("postProcessSummary");
}
}
public Document removeFields(Document document, String[] fields) {
for(String field : fields) {
document.remove(field);
}
return document;
}
private static final Log _log = LogFactoryUtil.getLog(
UserIndexerPostProcessor.class);
}
Is it because of the removal of the basic fields in overrided postProcessDocument method ?
Thanks a lot for your help,
Nils
Here is the code :
/**
* @author Liferay
*/
@Component(
immediate = true,
property = {
"indexer.class.name=com.liferay.portal.kernel.model.User"
},
service = IndexerPostProcessor.class
)
public class UserIndexerPostProcessor implements IndexerPostProcessor {
@Override
public void postProcessContextBooleanFilter(
BooleanFilter booleanFilter, SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessContextBooleanFilter");
}
}
@Override
public void postProcessContextQuery(
BooleanQuery contextQuery, SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessContextQuery");
}
}
@Override
public void postProcessDocument(Document document, Object obj)
throws Exception {
ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext();
Field userIdField = document.getField("entryClassPK");
String userId = userIdField.getValue();
User user = UserLocalServiceUtil.getUser(Long.parseLong(userId));
Field organizationIdsField = document.getField("organizationIds");
String[] organizations = organizationIdsField.getValues();
Contact contact = user.getContact();
List<Address> addresses = AddressLocalServiceUtil.getAddresses(user.getCompanyId(), "com.liferay.portal.kernel.model.Contact", contact.getContactId());
String[] fieldsToRemove = {"modified", "modified_sortable", "firstName_sortable", "groupId", "screenName", "scopeGroupId",
"organizationIds", "country", "entryClassPK"};
document = this.removeFields(document, fieldsToRemove);
document.addText("jobTitle", user.getJobTitle());
document.addText("country", addresses.get(0).getCountry().getName());
document.addText("id", userId);
document.addText("avatar", user.getPortraitURL(serviceContext.getThemeDisplay()));
try {
Field fPhones = new Field("phones");
List<Phone> phones = PhoneServiceUtil.getPhones("P", contact.getContactId());
for (Phone phone : phones) {
Field pNumber = new Field("number");
pNumber.setValue(phone.getNumber());
pNumber.setSortable(false);
pNumber.setParentField(fPhones);
Field pType = new Field("type");
pType.setValue(phone.getType().getName());
pType.setSortable(false);
pType.setParentField(fPhones);
Field pPrimary = new Field("primary");
pPrimary.setValue(String.valueOf(phone.isPrimary()));
pPrimary.setSortable(false);
pPrimary.setParentField(fPhones);
}
document.add(fPhones);
} catch(Exception e) {
e.printStackTrace();
}
Field fOrga = new Field("organisations");
List<Organization> organizations1 = OrganizationServiceUtil.getUserOrganizations(user.getUserId());
for (Organization orga : organizations1) {
Field oId = new Field("id");
oId.setValue(String.valueOf(orga.getOrganizationId()));
oId.setSortable(false);
oId.setParentField(fOrga);
Field oName = new Field("type");
oName.setValue(orga.getType());
oName.setSortable(false);
oName.setParentField(fOrga);
Field oprimary = new Field("primary");
oprimary.setValue(String.valueOf(orga.isRoot()));
oprimary.setSortable(false);
oprimary.setParentField(fOrga);
}
Field fMails = new Field("mails");
List<EmailAddress> mails = EmailAddressServiceUtil.getEmailAddresses("User", user.getUserId());
for (EmailAddress mail : mails) {
Field mMail = new Field("mail");
mMail.setValue(mail.getAddress());
mMail.setSortable(false);
mMail.setParentField(fMails);
Field mType = new Field("type");
mType.setValue(mail.getType().getName());
mType.setSortable(false);
mType.setParentField(fMails);
}
document.add(fMails);
String[] streets = {};
streets[0] = user.getAddresses().get(0).getStreet1();
streets[1] = user.getAddresses().get(0).getStreet2();
streets[2] = user.getAddresses().get(0).getStreet3();
document.addText("street", streets);
document.addText("isExecutive", "TODO");
if (_log.isInfoEnabled()) {
_log.info("postProcessDocument");
}
}
@Override
public void postProcessFullQuery(
BooleanQuery fullQuery, SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessFullQuery");
}
}
@Override
public void postProcessSearchQuery(
BooleanQuery searchQuery, BooleanFilter booleanFilter,
SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessSearchQuery");
}
}
@Override
public void postProcessSearchQuery(
BooleanQuery searchQuery, SearchContext searchContext)
throws Exception {
if (_log.isInfoEnabled()) {
_log.info("postProcessSearchQuery");
}
}
@Override
public void postProcessSummary(
Summary summary, Document document, Locale locale, String snippet) {
if (_log.isInfoEnabled()) {
_log.info("postProcessSummary");
}
}
public Document removeFields(Document document, String[] fields) {
for(String field : fields) {
document.remove(field);
}
return document;
}
private static final Log _log = LogFactoryUtil.getLog(
UserIndexerPostProcessor.class);
}
Is it because of the removal of the basic fields in overrided postProcessDocument method ?
Thanks a lot for your help,
Nils
I have review your IndexerPostProcessor and I think this is not a good idea:
String[] fieldsToRemove = {"modified", "modified_sortable", "firstName_sortable", "groupId", "screenName", "scopeGroupId",
"organizationIds", "country", "entryClassPK"};
document = this.removeFields(document, fieldsToRemove);
If you remove those fields, Liferay won't work properly.
String[] fieldsToRemove = {"modified", "modified_sortable", "firstName_sortable", "groupId", "screenName", "scopeGroupId",
"organizationIds", "country", "entryClassPK"};
document = this.removeFields(document, fieldsToRemove);
If you remove those fields, Liferay won't work properly.
Hi Jorge,I finally managed to get it working ! We already deleted this part of "field removal" but the error was in the last lines about the ExpandoBridge value. By debugging the postProcessDocument method step by step, I found out it left the method before finishing it, withour any error or exception, because of these lines.Thanks again for your precious help !