FAQ
Hi,

I have been working with Lucene for about a month now and I am really
impressed by the work of the people involved. I did, however, come across
something that I thought my be better refactored: extending the QueryParser
to add your own handling of various Query implementations. So I had a go at
introducing a QueryFactory interface that classes can implement to provide
construction of these Query implementations, and then an instance can be
passed to a QueryParser instance for it to use. I have a patch that provides
this if the developers of Lucene are interested but, because it is a quite
dramatic change (it removes alot of deprecated methods which I was very
worried about) I would prefer someone to take a look at it and see if they
think it is worthwhile.

The reason I made this patch is that I wanted to deal with integer ranges for
a particular field in my application and, like I said, extending QueryParser
felt wrong to me (and took me almost a week to actually find!). With the
patch I write:

QueryParser parser =
new QueryParser(
"description",
new StandardAnalyzer(),
new SpecialQueryFactory(new QueryFactoryImpl()));

And my specialised QueryFactory implementation gets used during parsing. The
implementation of QueryFactoryImpl was created by moving those methods that
created Query instances in the original QueryFactory into a separate class.
I also created a MultiFieldQueryFactory implementation that takes the methods
from MultiFieldQueryParser (effectively making it now redundant).

Personally I prefer the idea of composition over inheritance, in this
circumstance, but I can understand why other people would not want this.

Anyway, if someone would like to see the patch (made against the HEAD of the
Lucene CVS code) I can provide it; or you can tell me where to go! Either
way, Lucene has still made searching so much easier and I thank you.

Matt

---------------------------------------------------------------------
To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: lucene-dev-help@jakarta.apache.org

Search Discussions

  • David Spencer at Feb 7, 2005 at 7:17 pm
    This is interesting and may match what I've wanted - a way to register
    customized query expansion modules w/ the query parser so that you can
    experiment with different ways of expanding the query e.g. I wrote a
    "WordNet" package that's in the sandbox that expands terms by adding
    their synonyms e.g. "big" might expand to "big large^.9 huge^.9".

    So is it safe to assume I could use your code like this (with 2 lines
    changed from your example):

    QueryParser parser =
    new QueryParser(
    "synonym", // pseudo field?
    new StandardAnalyzer(),
    new SpecialQueryFactory(new WordNetQueryFactoryImpl())); //
    wordnet factory?

    Then a query can use the pseudo-field "synonym" any place:

    "+synonym:big dog"

    expands to:

    "+(big large^.9 huge^.9) dog"


    If so cool, I've wanted an extensible query parser for a while..

    thx,
    Dave

    PS
    When I wrote up my ideas on this a while ago I though the psuedo-field
    should look different from the normal fields e.g. it should have 2
    colons, not 1, but it's not a huge issue.




    Matthew Denner wrote:
    Hi,

    I have been working with Lucene for about a month now and I am really
    impressed by the work of the people involved. I did, however, come across
    something that I thought my be better refactored: extending the QueryParser
    to add your own handling of various Query implementations. So I had a go at
    introducing a QueryFactory interface that classes can implement to provide
    construction of these Query implementations, and then an instance can be
    passed to a QueryParser instance for it to use. I have a patch that provides
    this if the developers of Lucene are interested but, because it is a quite
    dramatic change (it removes alot of deprecated methods which I was very
    worried about) I would prefer someone to take a look at it and see if they
    think it is worthwhile.

    The reason I made this patch is that I wanted to deal with integer ranges for
    a particular field in my application and, like I said, extending QueryParser
    felt wrong to me (and took me almost a week to actually find!). With the
    patch I write:

    QueryParser parser =
    new QueryParser(
    "description",
    new StandardAnalyzer(),
    new SpecialQueryFactory(new QueryFactoryImpl()));

    And my specialised QueryFactory implementation gets used during parsing. The
    implementation of QueryFactoryImpl was created by moving those methods that
    created Query instances in the original QueryFactory into a separate class.
    I also created a MultiFieldQueryFactory implementation that takes the methods
    from MultiFieldQueryParser (effectively making it now redundant).

    Personally I prefer the idea of composition over inheritance, in this
    circumstance, but I can understand why other people would not want this.

    Anyway, if someone would like to see the patch (made against the HEAD of the
    Lucene CVS code) I can provide it; or you can tell me where to go! Either
    way, Lucene has still made searching so much easier and I thank you.

    Matt

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
    For additional commands, e-mail: lucene-dev-help@jakarta.apache.org

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
    For additional commands, e-mail: lucene-dev-help@jakarta.apache.org
  • Matthew Denner at Feb 7, 2005 at 8:13 pm

    On Monday 07 February 2005 19:17, David Spencer wrote:
    This is interesting and may match what I've wanted - a way to register
    customized query expansion modules w/ the query parser so that you can
    experiment with different ways of expanding the query e.g. I wrote a
    "WordNet" package that's in the sandbox that expands terms by adding
    their synonyms e.g. "big" might expand to "big large^.9 huge^.9".
    I took a quick look at the WordNet CVS and I'm not quite sure so I'm kind of
    working off what's below!
    So is it safe to assume I could use your code like this (with 2 lines
    changed from your example):

    QueryParser parser =
    new QueryParser(
    "synonym", // pseudo field?
    new StandardAnalyzer(),
    new SpecialQueryFactory(new WordNetQueryFactoryImpl())); //
    wordnet factory?
    It would probably be something like:

    QueryParser parser =
    new QueryParser(
    "defaultSearchField", // default search field (as normal)
    new StandardAnalyzer(),
    new WordNetQueryFactoryImpl("synonym", new QueryFactoryImpl()));

    I'm thinking that an instance of your QueryFactory implementation would
    effectively decorate another instance and might have your pseudo-field passed
    as a parameter. It would then be implemented to catch any pseudo-field (in
    this case "synonym") queries and process the text itself.
    Then a query can use the pseudo-field "synonym" any place:

    "+synonym:big dog"

    expands to:

    "+(big large^.9 huge^.9) dog"
    Your WordNetQueryFactoryImpl would be something like this:

    public class WordNetQueryFactoryImpl implements QueryFactory {
    private final QueryFactory m_delegate;
    private final String m_pseudoField;

    public WordNetQueryFactoryImpl(String pseudoField, QueryFactory delegate) {
    m_pseudoField = pseudoField;
    m_delegate = delegate;
    }

    // ... a few other interface methods here but cut for clarity ...

    public Query getFieldQuery(
    String field,
    Analyzer analyzer,
    String queryText,
    int slop)
    {
    // If the field is our pseudo-field and the value for it is 'big'
    if (m_pseudoField.equals(field) && "big".equals(queryText)) {
    // Use the delegate to build our query?
    BooleanQuery tmp = new BooleanQuery();
    tmp.add(
    m_delegate.getFieldQuery(field, analyzer, "big", slop),
    BooleanClause.Occur.SHOULD);
    tmp.add(
    m_delegate.getFieldQuery(field, analyzer, "large", slop),
    BooleanClause.Occur.SHOULD);
    tmp.add(
    m_delegate.getFieldQuery(field, analyzer, "huge", slop),
    BooleanClause.Occur.SHOULD);
    return tmp;
    } else {
    // ... otherwise delegate the handling to the other QueryFactory
    return m_delegate.getFieldQuery(field, analyzer, queryText, slop);
    }
    }
    }

    Just as an example, I'm sure you'll work out what I mean!
    If so cool, I've wanted an extensible query parser for a while..
    I don't think it quite fits an "extensible query parser", but I think it might
    get you somewhere.

    Matt

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
    For additional commands, e-mail: lucene-dev-help@jakarta.apache.org
  • Daniel Naber at Feb 7, 2005 at 7:18 pm

    On Monday 07 February 2005 17:56, Matthew Denner wrote:

    QueryParser parser =
    new QueryParser(
    "description",
    new StandardAnalyzer(),
    new SpecialQueryFactory(new QueryFactoryImpl()));
    This sounds interesting, could you create a bug report (see "Lucene Bugs"
    on the homepage) and then attach your patch?

    Regards
    Daniel

    --
    http://www.danielnaber.de

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
    For additional commands, e-mail: lucene-dev-help@jakarta.apache.org
  • Matthew Denner at Feb 7, 2005 at 8:40 pm

    On Monday 07 February 2005 19:19, Daniel Naber wrote:
    On Monday 07 February 2005 17:56, Matthew Denner wrote:
    QueryParser parser =
    new QueryParser(
    "description",
    new StandardAnalyzer(),
    new SpecialQueryFactory(new QueryFactoryImpl()));
    This sounds interesting, could you create a bug report (see "Lucene Bugs"
    on the homepage) and then attach your patch?
    I will do this I just need to finish off the unit-tests and work the changes
    into the QueryParser.jj file (I did them directly on the Java source). Would
    anyone mind if I added the MockObjects (http://www.mockobjects.com/) JAR as a
    dependency as it makes testing the LowerCaseQueryFactory and
    MultiFieldQueryFactory implementations slightly easier?

    Matt
  • Erik Hatcher at Feb 7, 2005 at 9:10 pm
    The MockObjects dependency is fine with me - it is a nice way to unit
    test for sure. The important thing is that it is Apache Software
    Licensed, which MO is.

    Erik


    On Feb 7, 2005, at 3:33 PM, Matthew Denner wrote:
    On Monday 07 February 2005 19:19, Daniel Naber wrote:
    On Monday 07 February 2005 17:56, Matthew Denner wrote:
    QueryParser parser =
    new QueryParser(
    "description",
    new StandardAnalyzer(),
    new SpecialQueryFactory(new QueryFactoryImpl()));
    This sounds interesting, could you create a bug report (see "Lucene
    Bugs"
    on the homepage) and then attach your patch?
    I will do this I just need to finish off the unit-tests and work the
    changes
    into the QueryParser.jj file (I did them directly on the Java source).
    Would
    anyone mind if I added the MockObjects (http://www.mockobjects.com/)
    JAR as a
    dependency as it makes testing the LowerCaseQueryFactory and
    MultiFieldQueryFactory implementations slightly easier?

    Matt

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
    For additional commands, e-mail: lucene-dev-help@jakarta.apache.org

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupjava-dev @
categorieslucene
postedFeb 7, '05 at 5:03p
activeFeb 7, '05 at 9:10p
posts6
users4
websitelucene.apache.org

People

Translate

site design / logo © 2021 Grokbase