com.ideabase.repository.common.Query.java Source code

Java tutorial

Introduction

Here is the source code for com.ideabase.repository.common.Query.java

Source

/*
 * $Id: Query.java 258 2008-03-10 19:02:20Z hasan $
 ******************************************************************************
 * Copyright (C) 2007 somewhere in .Net ltd.
 * All Rights Reserved.  No use, copying or distribution of this
 * work may be made except in accordance with a valid license
 * agreement from somewhere in .Net LTD.  This notice must be included on
 * all copies, modifications and derivatives of this work.
 ******************************************************************************
 * $LastChangedBy: hasan $
 * $LastChangedDate: 2008-03-11 00:32:20 +0530 (Tue, 11 Mar 2008) $
 * $LastChangedRevision: 258 $
 ******************************************************************************
*/
package com.ideabase.repository.common;

import org.apache.lucene.search.*;
import org.apache.lucene.index.Term;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

import com.ideabase.repository.common.exception.ServiceException;

/**
 * Query constructing utility class.
 * @author <a href="mailto:hasan@somewherein.net">nhm tanveer hossain khan (hasan)</a>
 */
public class Query {

    private static final String INDEX_DEFAULT = "default";

    private List<org.apache.lucene.search.Query> mAndQuries = new ArrayList<org.apache.lucene.search.Query>();
    private List<org.apache.lucene.search.Query> mOrQuries = new ArrayList<org.apache.lucene.search.Query>();
    private Map<String, Boolean> mSortBy = new HashMap<String, Boolean>();
    private Integer mMaxRows = Integer.MAX_VALUE;
    private Integer mSkipRows = 0;
    private float mScore = 0.0f;
    private BooleanQuery mBuiltQuery;
    private String mIndex = INDEX_DEFAULT;

    /**
     * Base query, the default value is null, if this value is not empty.
     * other conditions will be added with this query object.
     */
    private final org.apache.lucene.search.Query mBaseQuery;

    /**
     * Default constructor, it doesn't accept any argument.
     */
    public Query() {
        mBaseQuery = null;
    }

    /**
     * Constructor with {@see org.apache.lucene.search.Query} object.
     * @param pQuery pre parsed query.
     */
    public Query(final org.apache.lucene.search.Query pQuery) {
        mBaseQuery = pQuery;
    }

    /**
     * And add another new range query.
     * @param pField index field
     * @param pStart start value
     * @param pEnd end value.
     * @return self instance.
     */
    public Query andRange(final String pField, final String pStart, final String pEnd) {
        mAndQuries.add(new RangeQuery(new Term(pField, pStart), new Term(pField, pEnd), true));
        return this;
    }

    /**
     * Or add a new range query.
     * @param pField index field
     * @param pStart start value
     * @param pEnd end value.
     * @return self instance.
     */
    public Query orRange(final String pField, final String pStart, final String pEnd) {
        mOrQuries.add(new RangeQuery(new Term(pField, pStart), new Term(pField, pEnd), false));
        return this;
    }

    /**
     * Add required query expression.
     * @param pField query field name
     * @param pValue query field value.
     * @return the current instance of {@see Query} object, because it helps on
     *         method chaining.
     */
    public Query and(final String pField, final String pValue) {
        mAndQuries.add(new TermQuery(new Term(pField, pValue)));
        return this;
    }

    /**
     * Add optional query expression.
     * @param pField query field name.
     * @param pValue query field value.
     * @return the current instance of {@see Query} object, because it helps on
     *         method chaining.
     */
    public Query or(final String pField, final String pValue) {
        mOrQuries.add(new TermQuery(new Term(pField, pValue)));
        return this;
    }

    /**
     * Add option query expression which is matched for prefix only.
     * @param pField field name
     * @param pValue field value.
     * @return the current instance of {@see Query} object, because it helps on
     *         method chaining.
     */
    public Query orPrefix(final String pField, final String pValue) {
        mOrQuries.add(new PrefixQuery(new Term(pField, pValue)));
        return this;
    }

    /**
     * Required query expression which is matched for prefix only.
     * @param pField field name.
     * @param pValue field value.
     * @return the current instance of {@see Query} object, because it helps on
     *         method chaining.
     */
    public Query andPrefix(final String pField, final String pValue) {
        mOrQuries.add(new PrefixQuery(new Term(pField, pValue)));
        return this;
    }

    /**
     * Sort search result by the specified field in directed order.
     * @param pField field of indexed content
     * @param pDecending {@code true} if search result should be in decending ordered.
     * @return the current instance of (@see Query) object.
     */
    public Query sortBy(final String pField, final Boolean pDecending) {
        mSortBy.put(pField, pDecending);
        return this;
    }

    /**
     * Getter for sortable fields.
     * @return map of sortable fields.
     */
    public Map<String, Boolean> getSortableFields() {
        return mSortBy;
    }

    /**
     * set score for boosting search result.
     * @param pScore
     * @return self instance.
     */
    public Query score(final float pScore) {
        mScore = pScore;
        return this;
    }

    /**
     * Return suggested score boosting.
     * @return score
     */
    public float getScore() {
        return mScore;
    }

    /**
     * Set the maximum number of rows per search result.
     * @param pMaxRows maximum number of rows.
     * @return the current instance of {@see Query} object, because it helps on
     *         method chaining.
     */
    public Query maxRows(final Integer pMaxRows) {
        mMaxRows = pMaxRows;
        return this;
    }

    public Integer getMaxRows() {
        return mMaxRows;
    }

    /**
     * Set searchable index
     * @param pIndex searchable index name
     * @return self instance to keep the chain continuing.
     */
    public Query index(final String pIndex) {
        mIndex = pIndex;
        return this;
    }

    public String getIndex() {
        return mIndex.toLowerCase();
    }

    /**
     * Set the skipRows of the active record set.
     * @param pSkipRows the skipRows of the active record set.
     * @return the current instance of {@see Query} object, because it helps on
     *         method chaining.
     */
    public Query skipRows(final Integer pSkipRows) {
        mSkipRows = pSkipRows;
        return this;
    }

    public Integer getSkipRows() {
        return mSkipRows;
    }

    public List<org.apache.lucene.search.Query> getOrQueries() {
        return mOrQuries;
    }

    public List<org.apache.lucene.search.Query> getAndQueries() {
        return mAndQuries;
    }

    /**
     * Convert this query expression to {@see org.apache.lucene.search.Query}
     * object.<br> if base query object is defined, the current conditions
     * will be added with the base query.
     * @return lucene query object is returned.
     */
    public org.apache.lucene.search.Query buildQuery() {
        if (mBuiltQuery == null) {
            if (mAndQuries.isEmpty() && mOrQuries.isEmpty() && mBaseQuery == null) {
                throw new ServiceException(null, "No Query (AND, OR, PREFIX or " + "BaseQuery) is defined.");
            }
            // all quries are merged here.
            final BooleanQuery query = new BooleanQuery();

            // All required queries.
            if (!mAndQuries.isEmpty()) {
                for (final org.apache.lucene.search.Query andQuery : mAndQuries) {
                    query.add(andQuery, BooleanClause.Occur.MUST);
                }
            }

            // All optional quries.
            if (!mOrQuries.isEmpty()) {
                for (final org.apache.lucene.search.Query orQuery : mOrQuries) {
                    query.add(orQuery, BooleanClause.Occur.SHOULD);
                }
            }

            // set score for boosting search result
            if (mScore != 0.0f) {
                query.setBoost(mScore);
            }

            if (mBaseQuery != null) {
                // TODO: it set to required.
                // Add defined based query
                query.add(mBaseQuery, BooleanClause.Occur.MUST);
            }
            mBuiltQuery = query;
        }

        return mBuiltQuery;
    }

    @Override
    public String toString() {
        return ObjectToString.toString(this);
    }
}