SASM
SASM

Reputation: 1312

liferay lucene search not working

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.

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

Answers (1)

SASM
SASM

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

Related Questions