All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.appengine.api.search.dev.LuceneQueryBuilder Maven / Gradle / Ivy

Go to download

SDK for dev_appserver (local development) with some of the dependencies shaded (repackaged)

There is a newer version: 2.0.31
Show newest version
/*
 * Copyright 2021 Google LLC
 *
 * 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
 *
 *     https://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 language governing permissions and
 * limitations under the License.
 */

package com.google.appengine.api.search.dev;

import com.google.appengine.api.search.SearchQueryException;
import com.google.appengine.repackaged.com.google.appengine.api.search.proto.SearchServicePb.SearchParams;
import com.google.appengine.api.search.query.QueryParserFactory;
import com.google.appengine.api.search.query.QueryTreeBuilder;
import com.google.appengine.api.search.query.QueryTreeException;
import com.google.appengine.api.search.query.QueryTreeWalker;
import com.google.apphosting.api.search.DocumentPb;
import java.util.Map;
import java.util.Set;
import com.google.appengine.repackaged.org.antlr.runtime.RecognitionException;
import com.google.appengine.repackaged.org.antlr.runtime.tree.Tree;
import com.google.appengine.repackaged.org.apache.lucene.search.BooleanClause;
import com.google.appengine.repackaged.org.apache.lucene.search.BooleanQuery;
import com.google.appengine.repackaged.org.apache.lucene.search.Query;

/**
 * A builder of lucene queries. It uses the same parser as the one used by the
 * backend. Then, when traversing the resulting abstract search tree, it
 * generates a Lucene Query object.
 *
 */
class LuceneQueryBuilder {

  private final Map> allFieldTypes;

  LuceneQueryBuilder(Map> allFieldTypes) {
    this.allFieldTypes = allFieldTypes;
  }

  /**
   * Parses the user query and returns an equivalent Lucene query.
   *
   * @param searchParams search parameters (including query string) provided by the user.
   * @return an equivalent Lucene query
   * @throws SearchQueryException if the user query is invalid
   */
  Query parse(SearchParams searchParams) {
    String query = searchParams.getQuery();
    Query ret;
    try {
      Tree tree = new QueryTreeBuilder(new QueryParserFactory()).parse(query);
      if (tree == null) {
        throw new SearchQueryException("Null query not expected");
      }
      tree = QueryTreeWalker.simplify(tree);
      if (tree.getChildCount() == 0) {
        ret = LuceneUtils.getMatchAnyDocumentQuery();
      } else {
        LuceneQueryTreeVisitor visitor = new LuceneQueryTreeVisitor(allFieldTypes);
        QueryTreeWalker walker =
            new QueryTreeWalker(visitor);
        LuceneQueryTreeContext rootContext = LuceneQueryTreeContext.newRootContext();
        walker.walk(tree, rootContext);
        ret = rootContext.getQuery();
      }
    } catch (RecognitionException e) {
      String message = String.format("WARNING: query error at line %d:%d",
          e.line, e.charPositionInLine);
      SearchQueryException e2 = new SearchQueryException(message);
      e2.initCause(e);
      throw e2;
    } catch (QueryTreeException e) {
      SearchQueryException e2 = new SearchQueryException(e.getMessage());
      e2.initCause(e);
      throw e2;
    }
    if (searchParams.getFacetRefinementCount() != 0) {
      BooleanQuery combinedQuery = new BooleanQuery();
      combinedQuery.add(ret, BooleanClause.Occur.MUST);
      combinedQuery.add(SimpleFacet.getRefinementQuery(searchParams),
          BooleanClause.Occur.MUST);
      ret = combinedQuery;
    }
    return ret;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy