我正在尝试在Liferay 6.2中实现基于Lucene的索引和搜索。我有一个自定义服务生成器实体,并且希望能够搜索该实体的所有字段。但是问题在于,除非我在搜索框中明确键入field:value,否则它不会在所有索引字段中进行搜索。似乎只是在搜索liferay默认值,即

Field.ASSET_CATEGORY_TITLES, Field.ASSET_TAG_NAMES, Field.COMMENTS,
Field.CONTENT, Field.DESCRIPTION, Field.PROPERTIES, Field.TITLE,
Field.URL, Field.USER_NAME


这是我的实体

<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>


我已经成功索引了所有要搜索的字段,并且可以在Luke中看到它。

我在索引器中对其进行索引,如下所示:

@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;
    }


我还在localserviceimpl类中定义了Hits搜索方法:

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);
    }


我正在通过本地服务实用程序类从我的jsp调用此搜索方法。

因此,当我在搜索框中键入blood时,没有任何结果,但是当我键入materialType:blood时,却得到了结果。


对于空搜索,查询日志给了我
+(+((+(entryClassName:com.xxx.portlet.xxx.model.Sample))))(给出完整的结果集)
如果输入血,查询日志会给我

+(+((+(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*)

(空结果集)
如果我输入materialType:blood,查询日志会给我
+(+((+(entryClassName:com.xxx.portlet.xxx.model.Sample))))+(materialType:*blood* materialType:blood)(匹配结果集)


我想要的是用户能够只在框中键入自由文本并获取匹配的结果。但是目前这还行不通,因为自由文本搜索只是在liferay默认字段上搜索。我怎样才能解决这个问题?

该问题也发布在here上。

最佳答案

searchContext.setAttributes(attributes);类的Hits search method中设置localserviceimpl是不够的。我还必须重写postProcessSearchQuery类中的indexer方法。因此,在我的indexer类中添加了以下方法后,我开始使用它。

    @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);
            }
        }
    }

09-17 19:44