There are several steps to the query DSL:
 1. implement the initial ideas and see what problems we face and how well that fits
 2. add analyzers into the mix to transparently use the right one
 3. add parameters that use the conversion bridge (not sure how well that could fly but an interesting idea
 4. build up the stack of operators integrated into the DSL
 5. string based QL using this API (not convinced yet but why not).


Navin will start working on 1 and if things go well 2 (we will have a fantastic tool already we do just that).

Here are my notes based on the initial idea +  the feedback received.


A few remarks:
 - it asks the analyzer so that we correctly apply the analyzer on terms
 - it has a few query factory methods
 - it contains a few orthogonal operations
 - I am not quite satisfied with how boolean is handled, any idea?

Design remarks:
 - should we use interfaces or plain implementations? I would start with plain implementations to make things easier
 - let's put it in org.hibernate.search.query.dsl for now

Examples

SealedQueryBuilder qb = searchFactory.withEntityAnalyzer(Address.class);

Query luceneQuery = qb.must()
    .add(
        qb.should()
            .add( qb.term("city", "Atlanta").boostedTo(4).createQuery() )
            .add( qb.term("address1", "Peachtree").fuzzy().createQuery() )
    )
    .add(
        qb.range("movingDate").from("200604").to("201201").exclusive().createQuery()
    )
    .createQuery();
                     

Analyzer choice
queryBuilder.withAnalyzer(Analyzer)
queryBuilder.withEntityAnalyzer(Class<?>)
queryBuilder.basedOnEntityAnalyzer(Class<?>)
                    .overridesForField(String field, Analyzer)
                    .overridesForField(String field, Analyzer)
                    .build() //sucky name
returns a SealedQueryBuilder //sucky name

SealedQueryBuilder contains the factory methods


Factory methods
Hosted onSealedQueryBuilder

//Alternative
.term().on(String field).matches(String text)
.on(String field).matches(String text)


.term(String field, String text) //define a new query
.term(String field, String text) //define a new query
   .ignoreAnalyzer() //ignore the analyzer, optional
   .fuzzy() //API prevent wildcard calls, optional
     .threshold() //optional
     .prefixLengh() //optional
.term(String field, String value)
   .wildcard() //API prevent fuzzy calls, optional

//range query
.rangeQuery(String field)
    .from(String text)
    .to(String text)
    .exclusive() //optional
    .constantScore() //optional, due to constantScoreRangeQuery but in practice inherited from the common operations

//match all docs
.all() 

//phrase query
.phrase(String field)
    .ignoreAnalyzer() //ignore the analyzer, optional
    .addWord(String text) //at least one
    .addWord(String text)
    .sentence(String text) //do we need that?
    .slop() //optional

//search multiple fields for same value
.searchInMultipleFields()
  .onField(String field)
      .boostedTo(float) //optional
      .ignoreAnalyzer() //optional
  .onField(String field)
  .forWords(String) //do we need that?
  .forWord(String)


Boolean operations
SealedQueryBuilder contains the boolean methods

.must()
  .add( qb.from().to() )
  .add( ... )
.must().not()
.should()


Works on all queries
    .boostedTo()
    .constantScore() 
    .filter(Filter) //filter the current query
    .scoreMultipliedByField(field) //FieldScoreQuery + FunctionQuery?? //Not backed
    .createQuery()


Todo
Span*Queries
  
MultiPhraseQuery - needs to fillup all accepted terms
FieldScoreQuery
ValueSourceQuery
FuzzyLikeThis
MoreLikeThis