com.mathworks.xzheng.tools.CustomFlexibleQueryParser.java Source code

Java tutorial

Introduction

Here is the source code for com.mathworks.xzheng.tools.CustomFlexibleQueryParser.java

Source

package com.mathworks.xzheng.tools;

/**
 * Copyright Manning Publications Co.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific lan      
*/

import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryparser.flexible.core.QueryNodeException;
import org.apache.lucene.queryparser.flexible.core.builders.QueryTreeBuilder;
import org.apache.lucene.queryparser.flexible.core.nodes.FieldQueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.FuzzyQueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.QueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.SlopQueryNode;
import org.apache.lucene.queryparser.flexible.core.nodes.TokenizedPhraseQueryNode;
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorImpl;
import org.apache.lucene.queryparser.flexible.core.processors.QueryNodeProcessorPipeline;
import org.apache.lucene.queryparser.flexible.messages.MessageImpl;
import org.apache.lucene.queryparser.flexible.standard.StandardQueryParser;
import org.apache.lucene.queryparser.flexible.standard.builders.StandardQueryBuilder;
import org.apache.lucene.queryparser.flexible.standard.nodes.WildcardQueryNode;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanTermQuery;

// From chapter 9
public class CustomFlexibleQueryParser extends StandardQueryParser {

    public CustomFlexibleQueryParser(Analyzer analyzer) {
        super(analyzer);

        QueryNodeProcessorPipeline processors = (QueryNodeProcessorPipeline) getQueryNodeProcessor();
        processors.addProcessor(new NoFuzzyOrWildcardQueryProcessor()); //A

        QueryTreeBuilder builders = (QueryTreeBuilder) getQueryBuilder(); //B
        builders.setBuilder(TokenizedPhraseQueryNode.class, new SpanNearPhraseQueryBuilder());//B
        builders.setBuilder(SlopQueryNode.class, new SlopQueryNodeBuilder());//B
    }

    private final class NoFuzzyOrWildcardQueryProcessor extends QueryNodeProcessorImpl {
        protected QueryNode preProcessNode(QueryNode node) throws QueryNodeException {
            if (node instanceof FuzzyQueryNode || node instanceof WildcardQueryNode) { //C
                throw new QueryNodeException(new MessageImpl("no"));
            }
            return node;
        }

        protected QueryNode postProcessNode(QueryNode node) throws QueryNodeException {
            return node;
        }

        protected List<QueryNode> setChildrenOrder(List<QueryNode> children) {
            return children;
        }
    }

    private class SpanNearPhraseQueryBuilder implements StandardQueryBuilder {
        public Query build(QueryNode queryNode) throws QueryNodeException {
            TokenizedPhraseQueryNode phraseNode = (TokenizedPhraseQueryNode) queryNode;
            PhraseQuery phraseQuery = new PhraseQuery();

            List<QueryNode> children = phraseNode.getChildren(); //D

            SpanTermQuery[] clauses;
            if (children != null) {
                int numTerms = children.size();
                clauses = new SpanTermQuery[numTerms];
                for (int i = 0; i < numTerms; i++) {
                    FieldQueryNode termNode = (FieldQueryNode) children.get(i);
                    TermQuery termQuery = (TermQuery) termNode.getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);
                    clauses[i] = new SpanTermQuery(termQuery.getTerm());
                }
            } else {
                clauses = new SpanTermQuery[0];
            }

            return new SpanNearQuery(clauses, phraseQuery.getSlop(), true); //E
        }
    }

    public class SlopQueryNodeBuilder implements StandardQueryBuilder { //F

        public Query build(QueryNode queryNode) throws QueryNodeException {
            SlopQueryNode phraseSlopNode = (SlopQueryNode) queryNode;

            Query query = (Query) phraseSlopNode.getChild().getTag(QueryTreeBuilder.QUERY_TREE_BUILDER_TAGID);

            if (query instanceof PhraseQuery) {
                ((PhraseQuery) query).setSlop(phraseSlopNode.getValue());
            } else if (query instanceof MultiPhraseQuery) {
                ((MultiPhraseQuery) query).setSlop(phraseSlopNode.getValue());
            }

            return query;
        }
    }
}

/*
  #A Install our custom node processor
  #B Install our two custom query builders
  #C Prevent Fuzzy and Wildcard queries
  #D Pull all terms for phrase
  #E Create SpanNearQuery
  #F Override slop query node
*/