Reputation: 1312
I am trying to implement Lucene based indexing and searching in Liferay 6.2. I have a custom service builder entity and I want to be able to search on all the fields of this entity. But the problem is it is not searching on all the indexed fields unless I explicitly type the field:value
in the search box. It seems like it is just searching on liferay defaults which are
Field.ASSET_CATEGORY_TITLES, Field.ASSET_TAG_NAMES, Field.COMMENTS,
Field.CONTENT, Field.DESCRIPTION, Field.PROPERTIES, Field.TITLE,
Field.URL, Field.USER_NAME
This is my entity
<entity name="Sample" local-service="true" remote-service="true" table="sample">
<column name="uuid_" type="String" />
<column name="sampleDbId" type="long" primary="true" />
<column name="sampleCollectionDbId" type="long" />
<column name="biobankDbId" type="long" />
<column name="hashedSampleId" type="String" />
<column name="hashedIndividualId" type="String" />
<column name="materialType" type="String" />
<column name="container" type="String" />
<column name="storageTemperature" type="String" />
<column name="sampledTime" type="Date"/>
<column name="anatomicalPartOntology" type="String" />
<column name="anatomicalPartOntologyVersion" type="String" />
<column name="anatomicalPartOntologyCode" type="String" />
<column name="anatomicalPartOntologyDescription" type="String" />
<column name="anatomicalPartFreeText" type="String" />
<column name="sex" type="String" />
<column name="ageLow" type="long" />
<column name="ageHigh" type="long" />
<column name="ageUnit" type="String" />
<column name="diseaseOntology" type="String" />
<column name="diseaseOntologyVersion" type="String" />
<column name="diseaseOntologyCode" type="String" />
<column name="diseaseOntologyDescription" type="String" />
<column name="diseaseFreeText" type="String" />
<column name="countryOfOrigin" type="String" />
<finder name="uuid" return-type="Collection">
<finder-column name="uuid_" />
</finder>
</entity>
I have successfully indexed all the fields that I want to search and I can see it in Luke.
I am indexing it in my indexer as below:
@Override
protected Document doGetDocument(Object obj) throws Exception {
// TODO Auto-generated method stub
System.out.println("-----doGetDocument called------");
Sample sample = (Sample)obj;
Document document = getBaseModelDocument(PORTLET_ID, sample);
if(sample.getSampleCollectionDbId() > 0){
document.addText("sampleCollectionName", SampleCollectionLocalServiceUtil.getSampleCollection(sample.getSampleCollectionDbId()).getName());
}
document.add(new Field("biobankName", BiobankGeneralInformationLocalServiceUtil.getBiobankGeneralInformation(sample.getBiobankDbId()).getBiobankName()));
document.add(new Field("materialType", sample.getMaterialType()));
//document.addText("biobankName", BiobankGeneralInformationLocalServiceUtil.getBiobankGeneralInformation(sample.getBiobankDbId()).getBiobankName());
//document.addKeyword("materialType", sample.getMaterialType());
document.addKeyword("container", sample.getContainer());
document.addText("storageTemperature", sample.getStorageTemperature());
document.addDate("sampledTime", sample.getSampledTime());
document.addText("anatomicalPartOntology", sample.getAnatomicalPartOntology());
document.addKeyword("anatomicalPartOntologyVersion", sample.getAnatomicalPartOntologyVersion());
document.addKeyword("anatomicalPartOntologyCode", sample.getAnatomicalPartOntologyCode());
document.addText("anatomicalPartOntologyDescription", sample.getAnatomicalPartOntologyDescription());
document.addText("anatomicalPartFreeText", sample.getAnatomicalPartFreeText());
document.addKeyword("sex", sample.getSex());
document.addNumber("ageLow", sample.getAgeLow());
document.addNumber("ageHigh", sample.getAgeHigh());
document.addText("ageUnit", sample.getAgeUnit());
document.addText("diseaseOntology", sample.getDiseaseOntology());
document.addKeyword("diseaseOntologyVersion", sample.getDiseaseOntologyVersion());
document.addKeyword("diseaseOntologyCode", sample.getDiseaseOntologyCode());
document.addText("diseaseOntologyDescription", sample.getDiseaseOntologyDescription());
document.addText("diseaseFreeText", sample.getDiseaseFreeText());
document.addKeyword("countryOfOrigin", sample.getCountryOfOrigin());
return document;
}
I have also defined the Hits search method in my localserviceimpl class:
public Hits search(long companyId, String keywords) throws SearchException{
System.out.println("-----SampleLocalServiceImpl search called------");
SearchContext searchContext = new SearchContext();
searchContext.setAndSearch(false);
Map<String, Serializable> attributes = new HashMap<String, Serializable>();
attributes.put("sampleCollectionName", keywords);
attributes.put("biobankName", keywords);
attributes.put("materialType", keywords);
attributes.put("container", keywords);
attributes.put("storageTemperature", keywords);
attributes.put("sampledTime", keywords);
attributes.put("anatomicalPartOntology", keywords);
attributes.put("anatomicalPartOntologyVersion", keywords);
attributes.put("anatomicalPartOntologyCode", keywords);
attributes.put("anatomicalPartOntologyDescription", keywords);
attributes.put("anatomicalPartFreeText", keywords);
attributes.put("sex", keywords);
attributes.put("ageLow", keywords);
attributes.put("ageHigh", keywords);
attributes.put("ageUnit", keywords);
attributes.put("diseaseOntology", keywords);
attributes.put("diseaseOntologyVersion", keywords);
attributes.put("diseaseOntologyCode", keywords);
attributes.put("diseaseOntologyDescription", keywords);
attributes.put("diseaseFreeText", keywords);
attributes.put("countryOfOrigin", keywords);
searchContext.setAttributes(attributes);
searchContext.setCompanyId(companyId);
searchContext.setKeywords(keywords);
System.out.println(searchContext.getAttributes());
QueryConfig queryConfig = new QueryConfig();
queryConfig.setHighlightEnabled(false);
queryConfig.setScoreEnabled(false);
//searchContext.setAttribute("materialType:", keywords);
searchContext.setQueryConfig(queryConfig);
System.out.println(searchContext.getCompanyId());
Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
Sample.class);
System.out.println("-----SampleLocalServiceImpl search called------"+indexer.getFullQuery(searchContext));
System.out.println("-----SampleLocalServiceImpl search called------"+indexer);
return indexer.search(searchContext);
}
I am calling this search method from my jsp via localserviceutil class.
So when I type blood
in the search box, i get no results but when I type materialType:blood
I get the results back.
+(+((+(entryClassName:com.xxx.portlet.xxx.model.Sample))))
(gives full result set)If I type blood, the query log gives me
+(+((+(entryClassName:com.xxx.portlet.xxx.model.Sample)))) +(assetCategoryTitles:*blood* assetTagNames:*blood* comments:blood content:blood description:blood properties:blood title:blood
url:blood userName:*blood*)
(empty result set)
If I type materialType:blood, the query log gives me
+(+((+(entryClassName:com.xxx.portlet.xxx.model.Sample))))
+(materialType:*blood* materialType:blood)
(matching result set)
What I want is the user to be able to just type free text in the box and to get back the matching results. But at the moment this is not working as free text search is just searching on the liferay default fields. How can I fix this?
The question is also posted here.
Upvotes: 1
Views: 1744
Reputation: 1312
It was not enough to set searchContext.setAttributes(attributes);
in the Hits search method
of localserviceimpl
class. I also had to override the postProcessSearchQuery
method in my indexer
class. So after adding the following method in my indexer
class, I got it working.
@Override
public void postProcessSearchQuery(BooleanQuery searchQuery, SearchContext searchContext)
throws Exception {
System.out.println("-----postProcessSearchQuery called------");
addSearchTerm(searchQuery, searchContext, "sampleCollectionName", true);
addSearchTerm(searchQuery, searchContext, "biobankName", true);
addSearchTerm(searchQuery, searchContext, "materialType", true);
addSearchTerm(searchQuery, searchContext, "container", true);
addSearchTerm(searchQuery, searchContext, "storageTemperature", true);
.....
.....
LinkedHashMap<String, Object> params =
(LinkedHashMap<String, Object>)searchContext.getAttribute("params");
if (params != null) {
String expandoAttributes = (String)params.get("expandoAttributes");
if (Validator.isNotNull(expandoAttributes)) {
addSearchExpando(searchQuery, searchContext, expandoAttributes);
}
}
}
Upvotes: 1