com.liferay.portal.search.lucene33.LuceneIndexSearcherImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.portal.search.lucene33.LuceneIndexSearcherImpl.java

Source

/**
 * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.liferay.portal.search.lucene33;

import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.DocumentImpl;
import com.liferay.portal.kernel.search.Field;
import com.liferay.portal.kernel.search.Hits;
import com.liferay.portal.kernel.search.HitsImpl;
import com.liferay.portal.kernel.search.IndexSearcher;
import com.liferay.portal.kernel.search.Query;
import com.liferay.portal.kernel.search.SearchException;
import com.liferay.portal.kernel.search.Sort;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Time;
import com.liferay.portal.kernel.util.Validator;

import java.io.IOException;

import java.util.List;

import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;

/**
 * @author yoshinori koide
 */
public class LuceneIndexSearcherImpl implements IndexSearcher {

    public Hits search(long companyId, Query query, Sort[] sorts, int start, int end) throws SearchException {

        if (_log.isDebugEnabled()) {
            _log.debug("Query " + query);
        }

        Hits hits = null;

        org.apache.lucene.search.IndexSearcher searcher = null;
        org.apache.lucene.search.Sort luceneSort = null;

        try {
            searcher = LuceneHelperUtil.getSearcher(companyId, true);

            if (sorts != null) {
                searcher.setDefaultFieldSortScoring(true, true);

                SortField[] sortFields = new SortField[sorts.length];

                for (int i = 0; i < sorts.length; i++) {
                    Sort sort = sorts[i];

                    sortFields[i] = new SortField(sort.getFieldName(), sort.getType(), sort.isReverse());
                }

                luceneSort = new org.apache.lucene.search.Sort(sortFields);
            }

            long startTime = System.currentTimeMillis();

            org.apache.lucene.search.TopDocs luceneHits;

            if (luceneSort != null) {
                luceneHits = searcher.search(QueryTranslator.translate(query), Integer.MAX_VALUE, luceneSort);
            } else {
                luceneHits = searcher.search(QueryTranslator.translate(query), Integer.MAX_VALUE);
            }

            long endTime = System.currentTimeMillis();

            float searchTime = (float) (endTime - startTime) / Time.SECOND;

            hits = subset(searcher, luceneHits, query, startTime, searchTime, start, end);
        } catch (BooleanQuery.TooManyClauses tmc) {
            int maxClauseCount = BooleanQuery.getMaxClauseCount();

            BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE);

            try {
                long startTime = System.currentTimeMillis();

                org.apache.lucene.search.TopDocs luceneHits = searcher.search(QueryTranslator.translate(query),
                        Integer.MAX_VALUE);

                long endTime = System.currentTimeMillis();

                float searchTime = (float) (endTime - startTime) / Time.SECOND;

                hits = subset(searcher, luceneHits, query, startTime, searchTime, start, end);
            } catch (Exception e) {
                throw new SearchException(e);
            } finally {
                BooleanQuery.setMaxClauseCount(maxClauseCount);
            }
        } catch (ParseException pe) {
            _log.error("Query: " + query, pe);

            return new HitsImpl();
        } catch (Exception e) {
            throw new SearchException(e);
        } finally {
            try {
                if (searcher != null) {
                    searcher.close();
                }
            } catch (IOException ioe) {
                throw new SearchException(ioe);
            }
        }

        if (_log.isDebugEnabled()) {
            _log.debug("Search found " + hits.getLength() + " results in " + hits.getSearchTime() + "ms");
        }

        return hits;
    }

    protected DocumentImpl getDocument(org.apache.lucene.document.Document oldDoc) {

        DocumentImpl newDoc = new DocumentImpl();

        List<org.apache.lucene.document.Fieldable> oldFields = oldDoc.getFields();

        for (org.apache.lucene.document.Fieldable oldField : oldFields) {
            String[] values = oldDoc.getValues(oldField.name());

            if ((values != null) && (values.length > 1)) {
                Field newField = new Field(oldField.name(), values, oldField.isTokenized());

                newDoc.add(newField);
            } else {
                Field newField = new Field(oldField.name(), oldField.stringValue(), oldField.isTokenized());

                newDoc.add(newField);
            }
        }

        return newDoc;
    }

    protected String[] getQueryTerms(Query query) {
        String[] queryTerms = new String[0];

        try {
            queryTerms = LuceneHelperUtil.getQueryTerms(QueryTranslator.translate(query));
        } catch (ParseException pe) {
            _log.error("Query: " + query, pe);
        }

        return queryTerms;
    }

    protected String getSnippet(org.apache.lucene.document.Document doc, Query query, String field)
            throws IOException {

        String[] values = doc.getValues(field);

        String snippet = null;

        if (Validator.isNull(values)) {
            return snippet;
        }

        String s = StringUtil.merge(values);

        try {
            snippet = LuceneHelperUtil.getSnippet(QueryTranslator.translate(query), field, s);
        } catch (ParseException pe) {
            _log.error("Query: " + query, pe);
        }

        return snippet;
    }

    protected Hits subset(org.apache.lucene.search.IndexSearcher searcher, TopDocs luceneHits, Query query,
            long startTime, float searchTime, int start, int end) throws IOException {

        int length = luceneHits.totalHits;

        if ((start == QueryUtil.ALL_POS) && (end == QueryUtil.ALL_POS)) {
            start = 0;
            end = length;
        }

        String[] queryTerms = getQueryTerms(query);

        Hits subset = new HitsImpl();

        if ((start > -1) && (start <= end)) {
            if (end > length) {
                end = length;
            }

            int subsetTotal = end - start;

            Document[] subsetDocs = new DocumentImpl[subsetTotal];
            String[] subsetSnippets = new String[subsetTotal];
            float[] subsetScores = new float[subsetTotal];

            int j = 0;

            for (int i = start; i < end; i++, j++) {
                org.apache.lucene.document.Document doc = searcher.doc(luceneHits.scoreDocs[i].doc);

                subsetDocs[j] = getDocument(doc);
                subsetSnippets[j] = getSnippet(doc, query, Field.CONTENT);
                subsetScores[j] = luceneHits.scoreDocs[i].score;
            }

            subset.setStart(startTime);
            subset.setSearchTime(searchTime);
            subset.setQueryTerms(queryTerms);
            subset.setDocs(subsetDocs);
            subset.setLength(length);
            subset.setSnippets(subsetSnippets);
            subset.setScores(subsetScores);
        }

        return subset;
    }

    private static Log _log = LogFactoryUtil.getLog(LuceneIndexSearcherImpl.class);

}