Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

path query to support "contains" string query type #19

Open
jmrenouard opened this issue May 16, 2011 · 2 comments
Open

path query to support "contains" string query type #19

jmrenouard opened this issue May 16, 2011 · 2 comments

Comments

@jmrenouard
Copy link

The patch is very simple for play.module.search
In the functions count and executeQuery

        QueryParser qp= new QueryParser(Search.getLuceneVersion(), "_docID", Search.getAnalyser());
        qp.setAllowLeadingWildcard(true);

allow you to perform "contains" search AND start with search

the best could be :
using a parameter to manage this aspect in search

        QueryParser qp= new QueryParser(Search.getLuceneVersion(), "_docID", Search.getAnalyser());

        qp.setAllowLeadingWildcard(Boolean.parseBoolean(Play.configuration.getProperty(
                    "play.search.allowContainsRequest", "false")));

package play.modules.search;

import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;

import play.Play;
import play.db.jpa.JPA;
import play.db.jpa.JPABase;
import play.exceptions.UnexpectedException;
import play.modules.search.store.ConvertionUtils;
import play.modules.search.store.Store;
import play.modules.search.Search;
/**

  • Query API. This is a chainable API you get from Search.search () methods

  • @author jfp
    */
    public class Query {
    private Class clazz;

    protected String query;

    protected Store store;

    protected String[] order = new String[0];

    protected int offset = 0;

    protected int pageSize = 10;

    protected boolean reverse = false;

    protected IndexSearcher indexSearcher;

    protected TopDocs topDocs = null;

    protected Query(String query, Class clazz, Store store) {
    this.query = query;
    this.clazz = clazz;
    this.store = store;
    indexSearcher = store.getIndexSearcher(clazz.getName());
    }

    public Query page(int offset, int pageSize) {
    this.offset = offset;
    this.pageSize = pageSize;
    return this;
    }

    public Query all() {
    pageSize = -1;
    return this;
    }

    public Query reverse() {
    this.reverse = true;
    return this;
    }

    public Query orderBy(String... order) {
    this.order = new String[order.length];
    for (int i = 0; i < order.length; i++) {
    this.order[i] = order[i] + (ConvertionUtils.isForcedUntokenized(clazz, order[i]) ? "_untokenized" : "");
    }
    return this;
    }

    private Sort getSort() throws SearchException {
    Sort sort = new Sort();
    if (order.length > 0) {
    if (reverse) {
    if (order.length != 1)
    throw new SearchException("reverse can be used while sorting only one field with oderBy");
    sort.setSort(new SortField(order[0], ConvertionUtils.getSortType(clazz, order[0]), true));
    } else {
    SortField[] fields = new SortField[order.length];
    for (int i = 0; i < fields.length; i++) {
    fields[i] = new SortField(order[i], ConvertionUtils.getSortType(clazz, order[i]));
    }
    sort.setSort(fields);
    }
    }
    return sort;
    }

    /**

    • Executes the query and return directly JPABase objects (No score
    • information)
    • @return
      */
      @SuppressWarnings("unchecked")
      public List fetch() throws SearchException {
      try {
      List results = executeQuery(true);
      List objects = new ArrayList();
      for (QueryResult queryResult : results) {
      objects.add(queryResult.object);
      }
      return (List) objects;
      } catch (Exception e) {
      throw new UnexpectedException(e);
      }
      }

    public List fetchIds() throws SearchException {
    try {
    List results = executeQuery(false);
    List objects = new ArrayList();
    for (QueryResult queryResult : results) {
    objects.add(Long.parseLong(queryResult.id));
    }
    return objects;
    } catch (Exception e) {
    throw new UnexpectedException(e);
    }
    }

    public long count() throws SearchException {
    try {
    QueryParser qp= new QueryParser(Search.getLuceneVersion(), "_docID", Search.getAnalyser());
    qp.setAllowLeadingWildcard(Boolean.parseBoolean(Play.configuration.getProperty(
    "play.search.allowContainsRequest", "false")));
    org.apache.lucene.search.Query luceneQuery =qp.parse(query);
    topDocs = store.getIndexSearcher(clazz.getName()).search(luceneQuery, null, Integer.MAX_VALUE, getSort());
    return topDocs.totalHits;
    } catch (ParseException e) {
    throw new SearchException(e);
    } catch (Exception e) {
    throw new UnexpectedException(e);
    }
    }

    /**

    • Executes the lucene query against the index. You get QueryResults.

    • @param fetch load the corresponding JPABase objects in the QueryResult

    •        Object
      
    • @return
      */
      public List executeQuery(boolean fetch) throws SearchException {
      try {
      if (topDocs == null) {
      QueryParser qp= new QueryParser(Search.getLuceneVersion(), "_docID", Search.getAnalyser());
      qp.setAllowLeadingWildcard(Boolean.parseBoolean(Play.configuration.getProperty(
      "play.search.allowContainsRequest", "false")));
      org.apache.lucene.search.Query luceneQuery =qp.parse(query);
      BooleanQuery.setMaxClauseCount(Integer.parseInt(Play.configuration.getProperty(
      "play.search.maxClauseCount", "1024")));
      topDocs = indexSearcher.search(luceneQuery, null, Integer.MAX_VALUE, getSort());
      }
      List results = new ArrayList();
      if (topDocs == null)
      return results;

      int l = topDocs.totalHits;
      if (offset > l) {
          return results;
      }
      List<Long> ids = new ArrayList<Long>();
      if (pageSize > 0) {
          for (int i = offset; i < (offset + pageSize > l ? l : offset + pageSize); i++) {
              QueryResult qresult = new QueryResult();
              qresult.score = topDocs.scoreDocs[i].score;
              qresult.id = indexSearcher.doc(topDocs.scoreDocs[i].doc).get("_docID");
              if (fetch) {
                  Object objectId = ConvertionUtils.getIdValueFromIndex(clazz, qresult.id);
                  qresult.object = (JPABase)JPA.em().find(clazz, objectId);
                  if (qresult.object == null)
                      throw new SearchException("Please re-index");
              }
              results.add(qresult);
          }
      } else {
          for (int i = 0; i < l; i++) {
              QueryResult qresult = new QueryResult();
              qresult.score = topDocs.scoreDocs[i].score;
              qresult.id = indexSearcher.doc(topDocs.scoreDocs[i].doc).get("_docID");
              if (fetch) {
                  Object objectId = ConvertionUtils.getIdValueFromIndex(clazz, qresult.id);
                  qresult.object = (JPABase)JPA.em().find(clazz, objectId);
                  if (qresult.object == null)
                      throw new SearchException("Please re-index");
              }
              results.add(qresult);
          }
      }
      return results;
      

      } catch (ParseException e) {
      throw new SearchException(e);
      } catch (Exception e) {
      throw new UnexpectedException(e);
      }
      }

    public static class QueryResult {
    public String id;

    public float score;
    
    public JPABase object;
    

    }

    public static class SearchException extends RuntimeException {
    public SearchException(String message, Throwable cause) {
    super(message, cause);
    }

    public SearchException(Throwable cause) {
        super(cause);
    }
    
    public SearchException(String message) {
        super(message);
    }
    

    }
    }

@sebfroh
Copy link

sebfroh commented Sep 9, 2011

+1

1 similar comment
@mschaaf
Copy link

mschaaf commented Sep 9, 2011

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants